All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.opalj.collection.immutable.IntArraySet.scala Maven / Gradle / Ivy

The newest version!
/* BSD 2-Clause License - see OPAL/LICENSE for details. */
package org.opalj
package collection
package immutable

import java.util.{Arrays ⇒ JArrays}

import scala.collection.mutable.Builder

/**
 * A sorted set of integer values backed by an ordered array to store the values; this
 * guarantees log2(n) lookup.
 *
 * @author Michael Eichberg
 */
sealed abstract class IntArraySet
    extends (Int ⇒ Int)
    with IntSet[IntArraySet]
    with IntCollectionWithStableOrdering[IntArraySet] {

    /**
     * Returns each pairing of two values. I.e., if the set contains 1, 4, 8, the pairings
     * (1,4),(1,8) and (4,8) will be returned; the pairings (4,1) etc. will not be returned.
     * The order between the two values is not defined.
     */
    def foreachPair[U](f: (Int, Int) ⇒ U): Unit

    def reverseIntIterator: IntIterator

    def min: Int
    def max: Int
    final def last: Int = max

    final override def head: Int = min

    final override def toString: String = mkString("IntArraySet(", ",", ")")
}

case object EmptyIntArraySet extends IntArraySet {
    override def apply(index: Int): Int = throw new IndexOutOfBoundsException("empty")
    override def isSingletonSet: Boolean = false
    override def hasMultipleElements: Boolean = false
    override def isEmpty: Boolean = true
    override def size: Int = 0
    override def max: Int = throw new UnsupportedOperationException("empty set")
    override def min: Int = throw new UnsupportedOperationException("empty set")
    override def foreach[U](f: Int ⇒ U): Unit = {}
    override def foreachPair[U](f: (Int, Int) ⇒ U): Unit = {}
    override def withFilter(p: Int ⇒ Boolean): IntArraySet = this
    override def map(f: Int ⇒ Int): IntArraySet = this
    override def map(map: Array[Int]): IntArraySet = this
    override def flatMap(f: Int ⇒ IntArraySet): IntArraySet = this
    override def -(i: Int): this.type = this
    override def subsetOf(other: IntArraySet): Boolean = true
    override def +(i: Int): IntArraySet1 = new IntArraySet1(i)
    override def iterator: IntIterator = IntIterator.empty
    override def reverseIntIterator: IntIterator = IntIterator.empty
    override def contains(value: Int): Boolean = false
    override def exists(p: Int ⇒ Boolean): Boolean = false
    override def foldLeft[B](z: B)(f: (B, Int) ⇒ B): B = z
    override def forall(f: Int ⇒ Boolean): Boolean = true

    override def toChain: Chain[Int] = Naught

    override def equals(other: Any): Boolean = {
        other match {
            case is: IntArraySet ⇒ is.isEmpty
            case _               ⇒ false
        }
    }

    override def hashCode: Int = 1 // compatible to Arrays.hashCode
}

case class IntArraySet1(i: Int) extends IntArraySet {
    override def apply(index: Int): Int = {
        if (index == 0) i else throw new IndexOutOfBoundsException()
    }
    override def isEmpty: Boolean = false
    override def isSingletonSet: Boolean = true
    override def hasMultipleElements: Boolean = false
    override def foreach[U](f: Int ⇒ U): Unit = { f(i) }
    override def foreachPair[U](f: (Int, Int) ⇒ U): Unit = {}
    override def max: Int = this.i
    override def min: Int = this.i
    override def withFilter(p: Int ⇒ Boolean): IntArraySet = if (p(i)) this else EmptyIntArraySet
    override def map(f: Int ⇒ Int): IntArraySet = {
        val i = this.i
        val newI = f(i)
        if (newI != i)
            new IntArraySet1(newI)
        else
            this
    }
    override def map(map: Array[Int]): IntArraySet = {
        val mappedI = map(i)
        if (mappedI == i)
            this
        else
            new IntArraySet1(mappedI)
    }
    override def flatMap(f: Int ⇒ IntArraySet): IntArraySet = f(i)
    override def -(i: Int): IntArraySet = if (this.i != i) this else EmptyIntArraySet
    override def +(i: Int): IntArraySet = {
        val thisI = this.i
        if (thisI == i)
            this
        else if (thisI < i)
            new IntArraySet2(thisI, i)
        else
            new IntArraySet2(i, thisI)
    }
    override def iterator: IntIterator = IntIterator(i)
    override def reverseIntIterator: IntIterator = IntIterator(i)
    override def size: Int = 1

    override def contains(value: Int): Boolean = value == i
    override def exists(p: Int ⇒ Boolean): Boolean = p(i)
    override def foldLeft[B](z: B)(f: (B, Int) ⇒ B): B = f(z, i)
    override def forall(f: Int ⇒ Boolean): Boolean = f(i)

    override def toChain: Chain[Int] = new :&:[Int](i)

    override def equals(other: Any): Boolean = {
        other match {
            case is: IntArraySet ⇒ is.isSingletonSet && is.min == i
            case _               ⇒ false
        }
    }

    override def hashCode: Int = 31 + i // compatible to Arrays.hashCode
}

/**
 * Represents an orderd set of two values where i1 has to be smaller than i2.
 */
private[immutable] case class IntArraySet2(i1: Int, i2: Int) extends IntArraySet {

    assert(i1 < i2)

    override def apply(index: Int): Int = {
        index match {
            case 0 ⇒ i1
            case 1 ⇒ i2
            case _ ⇒ throw new IndexOutOfBoundsException()
        }
    }
    override def isEmpty: Boolean = false
    override def isSingletonSet: Boolean = false
    override def hasMultipleElements: Boolean = true
    override def size: Int = 2
    override def min: Int = this.i1
    override def max: Int = this.i2
    override def iterator: IntIterator = new IntIterator {
        private[this] var i = 0
        def hasNext: Boolean = i < 2
        def next(): Int = { i += 1; if (i == 1) i1 else i2 }
    }
    override def reverseIntIterator: IntIterator = IntIterator(i2, i1)
    override def foreach[U](f: Int ⇒ U): Unit = { f(i1); f(i2) }
    override def foreachPair[U](f: (Int, Int) ⇒ U): Unit = f(i1, i2)

    override def withFilter(p: Int ⇒ Boolean): IntArraySet = {
        if (p(i1)) {
            if (p(i2)) this
            else new IntArraySet1(i1)
        } else {
            if (p(i2)) new IntArraySet1(i2)
            else
                EmptyIntArraySet
        }
    }
    override def map(f: Int ⇒ Int): IntArraySet = {
        val i1 = this.i1
        val newI1 = f(i1)
        val i2 = this.i2
        val newI2 = f(i2)
        if (newI1 != i1 || newI2 != i2)
            IntArraySet(newI1, newI2) // ensures invariant
        else
            this
    }
    override def map(map: Array[Int]): IntArraySet = {
        IntArraySet2(map(i1), map(i2))
    }
    override def flatMap(f: Int ⇒ IntArraySet): IntArraySet = f(i1) ++ f(i2)
    override def -(i: Int): IntArraySet = {
        if (i == i1) new IntArraySet1(i2)
        else if (i == i2) new IntArraySet1(i1)
        else this
    }
    override def +(i: Int): IntArraySet = {
        if (i <= i1) {
            if (i == i1) this
            else new IntArraySet3(i, i1, i2)
        } else if (i <= i2) {
            if (i == i2) this
            else new IntArraySet3(i1, i, i2)
        } else {
            new IntArraySet3(i1, i2, i)
        }
    }
    override def contains(value: Int): Boolean = value == i1 || value == i2
    override def exists(p: Int ⇒ Boolean): Boolean = p(i1) || p(i2)
    override def foldLeft[B](z: B)(f: (B, Int) ⇒ B): B = f(f(z, i1), i2)
    override def forall(f: Int ⇒ Boolean): Boolean = f(i1) && f(i2)

    override def toChain: Chain[Int] = i1 :&: i2 :&: Naught

    override def equals(other: Any): Boolean = {
        other match {
            case is: IntArraySet ⇒ is.size == 2 && is.min == this.i1 && is.max == this.i2
            case _               ⇒ false
        }
    }

    override def hashCode: Int = 31 * (31 + i1) + i2 // compatible to Arrays.hashCode
}

/**
 * Represents an orderd set of three int values: i1 < i2 < i3.
 */
private[immutable] case class IntArraySet3(i1: Int, i2: Int, i3: Int) extends IntArraySet {

    assert(i1 < i2, s"i1 < i2: $i1 >= $i2")
    assert(i2 < i3, s"i2 < i3: $i2 >= $i3")

    override def apply(index: Int): Int = {
        index match {
            case 0 ⇒ i1
            case 1 ⇒ i2
            case 2 ⇒ i3
            case _ ⇒ throw new IndexOutOfBoundsException()
        }
    }
    override def isEmpty: Boolean = false
    override def isSingletonSet: Boolean = false
    override def hasMultipleElements: Boolean = true
    override def size: Int = 3
    override def min: Int = this.i1
    override def max: Int = this.i3

    override def iterator: IntIterator = new IntIterator {
        private[this] var i = 0
        def hasNext: Boolean = i < 3
        def next: Int = { i += 1; if (i == 1) i1 else if (i == 2) i2 else i3 }
    }
    override def reverseIntIterator: IntIterator = IntIterator(i3, i2, i1)
    override def foreach[U](f: Int ⇒ U): Unit = { f(i1); f(i2); f(i3) }
    override def foreachPair[U](f: (Int, Int) ⇒ U): Unit = { f(i1, i2); f(i1, i3); f(i2, i3) }

    override def withFilter(p: Int ⇒ Boolean): IntArraySet = {
        if (p(i1)) {
            if (p(i2)) {
                if (p(i3))
                    this
                else
                    new IntArraySet2(i1, i2)
            } else {
                if (p(i3))
                    new IntArraySet2(i1, i3)
                else
                    new IntArraySet1(i1)
            }
        } else {
            if (p(i2)) {
                if (p(i3))
                    new IntArraySet2(i2, i3)
                else
                    new IntArraySet1(i2)
            } else {
                if (p(i3))
                    new IntArraySet1(i3)
                else
                    IntArraySet.empty
            }
        }
    }
    override def map(f: Int ⇒ Int): IntArraySet = {
        val i1 = this.i1
        val newI1 = f(i1)
        val i2 = this.i2
        val newI2 = f(i2)
        val i3 = this.i3
        val newI3 = f(i3)
        if (newI1 != i1 || newI2 != i2 || newI3 != i3)
            IntArraySet(newI1, newI2, newI3) // ensures invariant
        else
            this
    }
    override def map(map: Array[Int]): IntArraySet = {
        IntArraySet3(map(i1), map(i2), map(i3))
    }
    override def flatMap(f: Int ⇒ IntArraySet): IntArraySet = f(i1) ++ f(i2) ++ f(i3)

    override def -(i: Int): IntArraySet = {
        if (i1 == i) new IntArraySet2(i2, i3)
        else if (i2 == i) new IntArraySet2(i1, i3)
        else if (i3 == i) new IntArraySet2(i1, i2)
        else this
    }
    override def +(i: Int): IntArraySet = {
        if (i < i2) {
            if (i < i1)
                new IntArraySetN(Array[Int](i, i1, i2, i3))
            else if (i == i1)
                this
            else
                new IntArraySetN(Array[Int](i1, i, i2, i3))
        } else if (i < i3) {
            if (i == i2)
                this
            else
                new IntArraySetN(Array[Int](i1, i2, i, i3))
        } else if (i == i3)
            this
        else
            new IntArraySetN(Array[Int](i1, i2, i3, i))
    }
    override def contains(value: Int): Boolean = value == i1 || value == i2 || value == i3
    override def exists(p: Int ⇒ Boolean): Boolean = p(i1) || p(i2) || p(i3)
    override def foldLeft[B](z: B)(f: (B, Int) ⇒ B): B = f(f(f(z, i1), i2), i3)
    override def forall(f: Int ⇒ Boolean): Boolean = f(i1) && f(i2) && f(i3)

    override def toChain: Chain[Int] = i1 :&: i2 :&: i3 :&: Naught

    override def equals(other: Any): Boolean = {
        other match {
            case that: IntArraySet ⇒
                that.size == 3 && this.i1 == that(0) && this.i2 == that(1) && this.i3 == that(2)
            case _ ⇒ false
        }
    }

    override def hashCode: Int = 31 * (31 * (31 + i1) + i2) + i3 // compatible to Arrays.hashCode
}

case class IntArraySetN private[immutable] (
        private[immutable] val is: Array[Int]
) extends IntArraySet {

    assert(is.length > 3)

    override def apply(index: Int): Int = is(index)
    override def size: Int = is.length
    override def isSingletonSet: Boolean = false
    override def hasMultipleElements: Boolean = true
    override def isEmpty: Boolean = false
    override def max: Int = is(is.length - 1)
    override def min: Int = is(0)

    override def foreach[U](f: Int ⇒ U): Unit = {
        val max = is.length
        var i = 0
        while (i < max) {
            f(is(i))
            i += 1
        }
    }
    override def foreachPair[U](f: (Int, Int) ⇒ U): Unit = {
        val max = is.length
        var i = 0
        while (i < max) {
            var j = i + 1
            while (j < max) {
                f(is(i), is(j))
                j += 1
            }
            i += 1
        }
    }

    override def withFilter(p: (Int) ⇒ Boolean): IntArraySet = {
        new FilteredIntArraySet(p, this)
    }

    override def map(f: Int ⇒ Int): IntArraySet = {
        // let's check if all values are mapped to their original values; if so return "this"
        val is = this.is
        val max = is.length
        var i = 0
        var f_is_i: Int = 0 // the initial value is never used!
        while (i < max && {
            val is_i = is(i)
            f_is_i = f(is_i)
            is_i == f_is_i
        }) { i += 1 }
        if (i == max)
            return this;

        val isb = new IntArraySetBuilder(max)
        var l = 0
        while (l < i) { isb += is(l) /*the values were unchanged*/ ; l += 1 }
        while (i < max) {
            isb += f(is(i))
            i += 1
        }
        isb.result()
    }
    override def map(map: Array[Int]): IntArraySet = {
        val is = this.is
        val max = is.length
        val isb = new IntArraySetBuilder(max)
        var i = 0
        while (i < max) {
            isb += map(is(i))
            i += 1
        }
        isb.result()
    }

    override def flatMap(f: Int ⇒ IntArraySet): IntArraySet = {
        foldLeft(EmptyIntArraySet: IntArraySet)(_ ++ f(_))
    }

    override def -(i: Int): IntArraySet = {
        val index = JArrays.binarySearch(is, 0, size, i)
        if (index >= 0) {
            if (is.length == 4) {
                index match {
                    case 0 ⇒ new IntArraySet3(is(1), is(2), is(3))
                    case 1 ⇒ new IntArraySet3(is(0), is(2), is(3))
                    case 2 ⇒ new IntArraySet3(is(0), is(1), is(3))
                    case 3 ⇒ new IntArraySet3(is(0), is(1), is(2))
                }
            } else {
                // the element is found
                val targetIs = new Array[Int](is.length - 1)
                System.arraycopy(is, 0, targetIs, 0, index)
                System.arraycopy(is, index + 1, targetIs, index, is.length - 1 - index)
                new IntArraySetN(targetIs)
            }
        } else {
            this
        }
    }

    override def +(i: Int): IntArraySet = {
        val index = JArrays.binarySearch(is, 0, size, i)
        if (index < 0) {
            val insertionPoint = -index - 1
            // the element is NOT already found
            val targetIs = new Array[Int](is.length + 1)
            System.arraycopy(is, 0, targetIs, 0, insertionPoint)
            targetIs(insertionPoint) = i
            val count = is.length - insertionPoint
            System.arraycopy(is, insertionPoint, targetIs, insertionPoint + 1, count)
            new IntArraySetN(targetIs)
        } else {
            this
        }
    }

    override def contains(value: Int): Boolean = {
        JArrays.binarySearch(is, 0, size, value) >= 0
    }

    override def exists(p: Int ⇒ Boolean): Boolean = {
        var i = 0
        val data = this.is
        val max = data.length
        while (i < max) { if (p(data(i))) return true; i += 1 }
        false
    }

    override def foldLeft[B](z: B)(f: (B, Int) ⇒ B): B = {
        var i = 0
        val data = this.is
        val max = data.length
        var r = z
        while (i < max) { r = f(r, data(i)); i += 1 }
        r
    }

    override def forall(p: Int ⇒ Boolean): Boolean = {
        var i = 0
        val data = this.is
        val max = data.length
        while (i < max) { if (!p(data(i))) return false; i += 1 }
        true
    }

    override def iterator: IntIterator = new IntIterator {
        private[this] var i = 0
        def hasNext: Boolean = i < is.length
        def next(): Int = { val i = this.i; this.i = i + 1; is(i) }
    }
    override def reverseIntIterator: IntIterator = new IntIterator {
        private[this] var i = is.length - 1
        def hasNext: Boolean = i >= 0
        def next(): Int = { val i = this.i; this.i = i - 1; is(i) }
    }

    override def toChain: Chain[Int] = {
        val cb = new Chain.ChainBuilder[Int]()
        foreach((i: Int) ⇒ cb += i)
        cb.result()
    }

    override def equals(other: Any): Boolean = {
        other match {
            case that: IntArraySet ⇒ that.size == this.size && this.subsetOf(that)
            case _                 ⇒ false
        }
    }

    override def hashCode: Int = JArrays.hashCode(is)
}

// TODO Reduce to "FilterMonadic" methods.
private[immutable] class FilteredIntArraySet(
        p: Int ⇒ Boolean, origS: IntArraySetN
) extends IntArraySet {

    @volatile private[this] var filteredS: IntArraySet = _

    private[this] def getFiltered: IntArraySet = {
        if (filteredS eq null) {
            this.synchronized {
                if (filteredS eq null) {
                    filteredS = {
                        val is = origS.is
                        val targetIs = new Array[Int](origS.size)
                        val max = is.length
                        var index = 0
                        var targetIsIndex = 0
                        while (index < max) {
                            if (p(is(index))) {
                                targetIs(targetIsIndex) = is(index)
                                targetIsIndex += 1
                            }
                            index += 1
                        }
                        targetIsIndex match {
                            case 0 ⇒ EmptyIntArraySet
                            case 1 ⇒ new IntArraySet1(targetIs(0))
                            case 2 ⇒ new IntArraySet2(targetIs(0), targetIs(1))
                            case 3 ⇒ new IntArraySet3(targetIs(0), targetIs(1), targetIs(2))
                            case _ ⇒
                                if (targetIsIndex == max) // no value was filtered...
                                    origS
                                else {
                                    new IntArraySetN(JArrays.copyOf(targetIs, targetIsIndex))
                                }

                        }
                    }
                }
            }
        }
        filteredS
    }

    override def apply(index: Int): Int = getFiltered.apply(index)

    override def withFilter(p: (Int) ⇒ Boolean): IntArraySet = {
        if (filteredS ne null) {
            filteredS.withFilter(p)
        } else {
            new FilteredIntArraySet((i: Int) ⇒ this.p(i) && p(i), origS)
        }
    }

    override def iterator: IntIterator = {
        if (filteredS ne null) {
            filteredS.iterator
        } else {
            origS.iterator.filter(p)
        }
    }

    override def reverseIntIterator: IntIterator = {
        if (filteredS ne null) {
            filteredS.reverseIntIterator
        } else {
            origS.reverseIntIterator.filter(p)
        }
    }

    override def foreach[U](f: Int ⇒ U): Unit = {
        if (filteredS ne null) {
            filteredS.foreach(f)
        } else {
            val is = origS.is
            val max = is.length
            var j = 0
            while (j < max) {
                val i = is(j)
                if (p(i)) f(i)
                j += 1
            }
        }
    }
    override def foreachPair[U](f: (Int, Int) ⇒ U): Unit = getFiltered.foreachPair(f)

    override def contains(value: Int): Boolean = p(value) && origS.contains(value)
    override def exists(p: Int ⇒ Boolean): Boolean = iterator.exists(p)
    override def foldLeft[B](z: B)(f: (B, Int) ⇒ B): B = iterator.foldLeft(z)(f)
    override def forall(p: Int ⇒ Boolean): Boolean = iterator.forall(p)

    override def size: Int = getFiltered.size
    override def isSingletonSet: Boolean = getFiltered.isSingletonSet
    override def hasMultipleElements: Boolean = getFiltered.hasMultipleElements
    override def isEmpty: Boolean = getFiltered.isEmpty
    override def min: Int = getFiltered.min
    override def max: Int = getFiltered.max
    override def map(f: Int ⇒ Int): IntArraySet = getFiltered.map(f)
    override def map(map: Array[Int]): IntArraySet = getFiltered.map(map)
    override def flatMap(f: Int ⇒ IntArraySet): IntArraySet = getFiltered.flatMap(f)
    override def -(i: Int): IntArraySet = getFiltered - i
    override def +(i: Int): IntArraySet = getFiltered + 1
    override def toChain: Chain[Int] = iterator.toChain
    override def equals(other: Any): Boolean = getFiltered.equals(other)
    override def hashCode: Int = getFiltered.hashCode
}

class IntArraySetBuilder private[immutable] (
        private[this] var is:   Array[Int],
        private[this] var size: Int
) extends Builder[Int, IntArraySet] {

    require(size <= is.length)

    // TODO implement sizeHint...
    def this() { this(new Array[Int](4), 0) }

    def this(initialSize: Int) { this(new Array[Int](Math.max(initialSize, 4)), 0) }

    override def +=(elem: Int): this.type = {
        import System.arraycopy
        val index = JArrays.binarySearch(is, 0, size, elem)
        if (index < 0) {
            // the element is NOT already found
            size += 1
            val insertionPoint = -index - 1
            if ( /*new*/ size <= is.length) { // we have enough space
                arraycopy(is, insertionPoint, is, insertionPoint + 1, (size - 1) - insertionPoint)
                is(insertionPoint) = elem
            } else {
                val targetIs = new Array[Int](is.length * 2)
                arraycopy(is, 0, targetIs, 0, insertionPoint)
                targetIs(insertionPoint) = elem
                val count = is.length - insertionPoint
                arraycopy(is, insertionPoint, targetIs, insertionPoint + 1, count)
                is = targetIs
            }
        }

        this
    }

    def ++=(elems: IntArraySet): this.type = { elems.foreach(this.+=); this }

    override def clear(): Unit = { is = new Array[Int](4); size = 0 }

    override def result(): IntArraySet = {
        size match {
            case 0 ⇒ EmptyIntArraySet
            case 1 ⇒ new IntArraySet1(is(0))
            case 2 ⇒ new IntArraySet2(is(0), is(1))
            case 3 ⇒ new IntArraySet3(is(0), is(1), is(2))
            case _ ⇒
                if (size == is.length)
                    new IntArraySetN(is)
                else {
                    val targetIs = new Array[Int](size)
                    System.arraycopy(is, 0, targetIs, 0, size)
                    new IntArraySetN(targetIs)
                }

        }
    }

    override def toString: String = {
        is.mkString(s"IntArraySetBuilder(size=$size;values={", ",", "})")
    }
}

object IntArraySetBuilder {

    def apply(vs: Int*): IntArraySetBuilder = {
        val isb = new IntArraySetBuilder(new Array[Int](vs.size), 0)
        vs.foreach(isb.+=)
        isb
    }

    def apply(vs: Set[Int]): IntArraySetBuilder = {
        val isb = new IntArraySetBuilder(new Array[Int](Math.max(4, vs.size)), 0)
        vs.foreach(isb.+=)
        isb
    }

    def apply(c: Chain[Int]): IntArraySetBuilder = {
        val isb = new IntArraySetBuilder(new Array[Int](4), 0)
        c.foreach(isb.+=)
        isb
    }
}

object IntArraySet {

    def empty: IntArraySet = EmptyIntArraySet

    def apply(i: Int): IntArraySet = new IntArraySet1(i)

    def apply(i1: Int, i2: Int): IntArraySet = {
        if (i1 < i2) new IntArraySet2(i1, i2)
        else if (i1 == i2) new IntArraySet1(i1)
        else IntArraySet2(i2, i1)
    }

    def apply(i1: Int, i2: Int, i3: Int): IntArraySet = {
        if (i1 == i2)
            return IntArraySet(i2, i3);
        if (i1 == i3 || i2 == i3)
            return if (i1 < i2) new IntArraySet2(i1, i2) else new IntArraySet2(i2, i1);

        //... all three values are different
        var v0 = 0
        var v1 = 0
        if (i1 < i2) {
            v0 = i1
            v1 = i2
        } else {
            v0 = i2
            v1 = i1
        }
        if (i3 < v1) {
            if (i3 < v0) new IntArraySet3(i3, v0, v1)
            else new IntArraySet3(v0, i3, v1)
        } else {
            new IntArraySet3(v0, v1, i3)
        }
    }

    /**
     * Constructs a sorted `IntArraySet` from given sorted (according to the natural order) array;
     * ''potentially reusing the given array''.
     */
    def _UNSAFE_fromSorted(data: Array[Int]): IntArraySet = {
        data.length match {
            case 0 ⇒ EmptyIntArraySet
            case 1 ⇒ new IntArraySet1(data(0))
            case 2 ⇒ new IntArraySet2(data(0), data(1))
            case 3 ⇒ new IntArraySet3(data(0), data(1), data(2))
            case _ ⇒ new IntArraySetN(data)
        }
    }

    def _UNSAFE_from(data: Array[Int]): IntArraySet = {
        data.length match {
            case 0 ⇒ EmptyIntArraySet
            case 1 ⇒ new IntArraySet1(data(0))
            case 2 ⇒ IntArraySet(data(0), data(1))
            case 3 ⇒ IntArraySet(data(0), data(1), data(2))
            case _ ⇒ { JArrays.parallelSort(data); new IntArraySetN(data) }
        }
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy