diff --git a/src/dorkbox/collections/ArrayMap.kt b/src/dorkbox/collections/ArrayMap.kt index 71519f8..8437c4b 100644 --- a/src/dorkbox/collections/ArrayMap.kt +++ b/src/dorkbox/collections/ArrayMap.kt @@ -193,7 +193,7 @@ class ArrayMap : MutableMap{ } fun putAll(map: ArrayMap, offset: Int = 0, length: Int = map.size_) { - require(offset + length <= map.size_) { "offset + length must be <= size: $offset + $length <= ${map.size_}" } + if (offset + length > map.size_) { throw StateException("offset + length must be <= size: $offset + $length <= ${map.size_}") } val sizeNeeded = size_ + length - offset if (sizeNeeded >= keyTable.size) { @@ -532,7 +532,8 @@ class ArrayMap : MutableMap{ * many entries to avoid multiple backing array resizes. */ fun ensureCapacity(additionalCapacity: Int) { - require(additionalCapacity >= 0) { "additionalCapacity must be >= 0: $additionalCapacity" } + if (additionalCapacity < 0) { throw StateException("additionalCapacity must be >= 0: $additionalCapacity") } + val sizeNeeded = size_ + additionalCapacity if (sizeNeeded > keyTable.size) resize( max(max(8.0, sizeNeeded.toDouble()), (size_ * 1.75f).toInt().toDouble()).toInt() diff --git a/src/dorkbox/collections/BinarySearch.kt b/src/dorkbox/collections/BinarySearch.kt index 6bcb6f2..a9ed34f 100644 --- a/src/dorkbox/collections/BinarySearch.kt +++ b/src/dorkbox/collections/BinarySearch.kt @@ -83,7 +83,7 @@ class BinarySearch(private val eval: Evaluator, private val indexed: Index val t = indexed[i] val nue = eval.getValue(t) if (`val` != Long.MIN_VALUE) { - require(nue >= `val`) { "Collection is not sorted at " + i + " - " + indexed } + if (nue < `val`) { throw StateException("Collection is not sorted at " + i + " - " + indexed) } } `val` = nue } diff --git a/src/dorkbox/collections/ExpandingArray.kt b/src/dorkbox/collections/ExpandingArray.kt index 0b83ebd..56829f8 100644 --- a/src/dorkbox/collections/ExpandingArray.kt +++ b/src/dorkbox/collections/ExpandingArray.kt @@ -165,7 +165,8 @@ class ExpandingArray : MutableIterable { } fun addAll(array: ExpandingArray, start: Int, count: Int) { - require(start + count <= array.size) { "start + count must be <= size: " + start + " + " + count + " <= " + array.size } + if (start + count > array.size) { throw StateException("start + count must be <= size: $start + $count <= ${array.size}") } + @Suppress("UNCHECKED_CAST") addAll(array.items as Array, start, count) } @@ -503,7 +504,8 @@ class ExpandingArray : MutableIterable { * @return [.items] */ fun ensureCapacity(additionalCapacity: Int): Array { - require(additionalCapacity >= 0) { "additionalCapacity must be >= 0: $additionalCapacity" } + if (additionalCapacity < 0) { throw StateException("additionalCapacity must be >= 0: $additionalCapacity") } + val sizeNeeded = size + additionalCapacity if (sizeNeeded > items.size) resize( max(max(8.0, sizeNeeded.toDouble()), (size * 1.75f).toInt().toDouble()).toInt() @@ -643,7 +645,8 @@ class ExpandingArray : MutableIterable { * taken. */ fun truncate(newSize: Int) { - require(newSize >= 0) { "newSize must be >= 0: $newSize" } + if (newSize < 0) { throw StateException("newSize must be >= 0: $newSize") } + if (size <= newSize) return for (i in newSize until size) items[i] = null size = newSize diff --git a/src/dorkbox/collections/IntFloatMap.kt b/src/dorkbox/collections/IntFloatMap.kt index 3838a77..add558c 100644 --- a/src/dorkbox/collections/IntFloatMap.kt +++ b/src/dorkbox/collections/IntFloatMap.kt @@ -115,7 +115,7 @@ class IntFloatMap : MutableMap { * @param loadFactor The loadfactor used to determine backing array growth */ constructor(initialCapacity: Int = 51, loadFactor: Float = 0.8f) { - require(!(loadFactor <= 0f || loadFactor >= 1f)) { "loadFactor must be > 0 and < 1: $loadFactor" } + if ((loadFactor <= 0f || loadFactor >= 1f)) { throw StateException("loadFactor must be > 0 and < 1: $loadFactor") } this.loadFactor = loadFactor val tableSize = tableSize(initialCapacity, loadFactor) @@ -306,7 +306,8 @@ class IntFloatMap : MutableMap { * instead. */ fun shrink(maximumCapacity: Int) { - require(maximumCapacity >= 0) { "maximumCapacity must be >= 0: $maximumCapacity" } + if (maximumCapacity < 0) { throw StateException("maximumCapacity must be >= 0: $maximumCapacity") } + val tableSize = tableSize(maximumCapacity, loadFactor) if (keyTable.size > tableSize) resize(tableSize) } diff --git a/src/dorkbox/collections/IntIntMap.kt b/src/dorkbox/collections/IntIntMap.kt index f4b8a07..c649bd9 100644 --- a/src/dorkbox/collections/IntIntMap.kt +++ b/src/dorkbox/collections/IntIntMap.kt @@ -115,7 +115,7 @@ class IntIntMap : MutableMap { * @param loadFactor The loadfactor used to determine backing array growth */ constructor(initialCapacity: Int = 51, loadFactor: Float = 0.8f) { - require(!(loadFactor <= 0f || loadFactor >= 1f)) { "loadFactor must be > 0 and < 1: $loadFactor" } + if ((loadFactor <= 0f || loadFactor >= 1f)) { throw StateException("loadFactor must be > 0 and < 1: $loadFactor") } this.loadFactor = loadFactor val tableSize = tableSize(initialCapacity, loadFactor) @@ -306,7 +306,8 @@ class IntIntMap : MutableMap { * instead. */ fun shrink(maximumCapacity: Int) { - require(maximumCapacity >= 0) { "maximumCapacity must be >= 0: $maximumCapacity" } + if (maximumCapacity < 0) { throw StateException("maximumCapacity must be >= 0: $maximumCapacity") } + val tableSize = tableSize(maximumCapacity, loadFactor) if (keyTable.size > tableSize) resize(tableSize) } diff --git a/src/dorkbox/collections/IntMap.kt b/src/dorkbox/collections/IntMap.kt index 86c76cf..cff7c78 100644 --- a/src/dorkbox/collections/IntMap.kt +++ b/src/dorkbox/collections/IntMap.kt @@ -116,7 +116,7 @@ open class IntMap : MutableMap { * @param loadFactor The loadfactor used to determine backing array growth */ constructor(initialCapacity: Int = 51, loadFactor: Float = 0.8f) { - require(!(loadFactor <= 0f || loadFactor >= 1f)) { "loadFactor must be > 0 and < 1: $loadFactor" } + if ((loadFactor <= 0f || loadFactor >= 1f)) { throw StateException("loadFactor must be > 0 and < 1: $loadFactor") } this.loadFactor = loadFactor val tableSize = tableSize(initialCapacity, loadFactor) @@ -308,7 +308,8 @@ open class IntMap : MutableMap { * instead. */ open fun shrink(maximumCapacity: Int) { - require(maximumCapacity >= 0) { "maximumCapacity must be >= 0: $maximumCapacity" } + if (maximumCapacity < 0) { throw StateException("maximumCapacity must be >= 0: $maximumCapacity") } + val tableSize = tableSize(maximumCapacity, loadFactor) if (keyTable.size > tableSize) resize(tableSize) } diff --git a/src/dorkbox/collections/IntSet.kt b/src/dorkbox/collections/IntSet.kt index 82fcab9..17eb18f 100644 --- a/src/dorkbox/collections/IntSet.kt +++ b/src/dorkbox/collections/IntSet.kt @@ -110,7 +110,8 @@ class IntSet: MutableSet { * @param loadFactor The loadfactor used to determine backing array growth */ constructor(initialCapacity: Int = 51, loadFactor: Float = 0.8f) { - require(!(loadFactor <= 0f || loadFactor >= 1f)) { "loadFactor must be > 0 and < 1: $loadFactor" } + if ((loadFactor <= 0f || loadFactor >= 1f)) { throw StateException("loadFactor must be > 0 and < 1: $loadFactor") } + this.loadFactor = loadFactor val tableSize = tableSize(initialCapacity, loadFactor) threshold = (tableSize * loadFactor).toInt() @@ -203,7 +204,8 @@ class IntSet: MutableSet { } fun addAll(array: IntArray, offset: Int, length: Int) { - require(offset + length <= array.size) { "offset + length must be <= size: $offset + $length <= ${array.size}" } + if (offset + length > array.size) { throw StateException("offset + length must be <= size: $offset + $length <= ${array.size}") } + ensureCapacity(length) var i = offset @@ -293,7 +295,8 @@ class IntSet: MutableSet { * instead. */ fun shrink(maximumCapacity: Int) { - require(maximumCapacity >= 0) { "maximumCapacity must be >= 0: $maximumCapacity" } + if (maximumCapacity < 0) { throw StateException("maximumCapacity must be >= 0: $maximumCapacity") } + val tableSize = tableSize(maximumCapacity, loadFactor) if (keyTable.size > tableSize) resize(tableSize) } diff --git a/src/dorkbox/collections/LockFreeBiMap.kt b/src/dorkbox/collections/LockFreeBiMap.kt index aa0e817..b54138c 100644 --- a/src/dorkbox/collections/LockFreeBiMap.kt +++ b/src/dorkbox/collections/LockFreeBiMap.kt @@ -95,23 +95,17 @@ class LockFreeBiMap : MutableMap, Cloneable, Serializable * * @throws NullPointerException if the specified map is null * - * @throws IllegalArgumentException if a given value in the map is already bound to a different key in this bimap. The bimap will remain + * @throws StateException if a given value in the map is already bound to a different key in this bimap. The bimap will remain * unmodified in this event. To avoid this exception, call [.replaceAllForce] replaceAllForce(map) instead. */ @Synchronized - @Throws(IllegalArgumentException::class) + @Throws(StateException::class) fun replaceAll(hashMap: Map?) { if (hashMap == null) { throw NullPointerException("hashMap") } val biMap = LockFreeBiMap() - try { - biMap.putAll(hashMap) - } - catch (e: IllegalArgumentException) { - // do nothing if there is an exception - throw e - } + biMap.putAll(hashMap) // only if there are no problems with the creation of the new bimap. forwardHashMap.clear() @@ -158,11 +152,11 @@ class LockFreeBiMap : MutableMap, Cloneable, Serializable * (A null return can also indicate that the map * previously associated null with key.) * - * @throws IllegalArgumentException if the given value is already bound to a different key in this bimap. The bimap will remain + * @throws StateException if the given value is already bound to a different key in this bimap. The bimap will remain * unmodified in this event. To avoid this exception, call [.putForce] putForce(K, V) instead. */ @Synchronized - @Throws(IllegalArgumentException::class) + @Throws(StateException::class) override fun put(key: K, value: V): V? { val prevForwardValue = forwardHashMap.put(key, value) if (prevForwardValue != null) { @@ -178,7 +172,7 @@ class LockFreeBiMap : MutableMap, Cloneable, Serializable forwardHashMap.remove(key) } reverseHashMap[value] = prevReverseValue - throw IllegalArgumentException("Value already exists. Keys and values must both be unique!") + throw StateException("Value already exists. Keys and values must both be unique!") } return prevForwardValue } @@ -219,19 +213,19 @@ class LockFreeBiMap : MutableMap, Cloneable, Serializable * * @throws NullPointerException if the specified map is null * - * @throws IllegalArgumentException if the given value is already bound to a different key in this bimap. The bimap will remain + * @throws StateException if the given value is already bound to a different key in this bimap. The bimap will remain * unmodified in this event. To avoid this exception, call [.putAllForce] putAllForce(K, V) instead. */ @Synchronized - @Throws(IllegalArgumentException::class) + @Throws(StateException::class) override fun putAll(from: Map) { val biMap = LockFreeBiMap() for ((key, value) in from) { biMap.put(key, value) // we have to verify that the keys/values between the bimaps are unique - require(!forwardHashMap.containsKey(key)) { "Key already exists. Keys and values must both be unique!" } - require(!reverseHashMap.containsKey(value)) { "Value already exists. Keys and values must both be unique!" } + if (forwardHashMap.containsKey(key)) { throw StateException("Key already exists. Keys and values must both be unique!") } + if (reverseHashMap.containsKey(value)) { throw StateException("Value already exists. Keys and values must both be unique!") } } diff --git a/src/dorkbox/collections/LockFreeHashMap.kt b/src/dorkbox/collections/LockFreeHashMap.kt index 59f9dac..d256115 100644 --- a/src/dorkbox/collections/LockFreeHashMap.kt +++ b/src/dorkbox/collections/LockFreeHashMap.kt @@ -58,7 +58,7 @@ class LockFreeHashMap : MutableMap, Cloneable, Serializable { * * @param initialCapacity the initial capacity. * - * @throws IllegalArgumentException if the initial capacity is negative. + * @throws StateException if the initial capacity is negative. */ constructor(initialCapacity: Int) { hashMap = HashMap(initialCapacity) @@ -89,7 +89,7 @@ class LockFreeHashMap : MutableMap, Cloneable, Serializable { * @param initialCapacity the initial capacity * @param loadFactor the load factor * - * @throws IllegalArgumentException if the initial capacity is negative + * @throws StateException if the initial capacity is negative * or the load factor is nonpositive */ constructor(initialCapacity: Int, loadFactor: Float) { diff --git a/src/dorkbox/collections/LockFreeIntBiMap.kt b/src/dorkbox/collections/LockFreeIntBiMap.kt index 9b59a0c..776d30e 100644 --- a/src/dorkbox/collections/LockFreeIntBiMap.kt +++ b/src/dorkbox/collections/LockFreeIntBiMap.kt @@ -103,23 +103,17 @@ class LockFreeIntBiMap : MutableMap, Cloneable, Serializable { * * @throws NullPointerException if the specified map is null * - * @throws IllegalArgumentException if a given value in the map is already bound to a different key in this bimap. The bimap will remain + * @throws StateException if a given value in the map is already bound to a different key in this bimap. The bimap will remain * unmodified in this event. To avoid this exception, call [.replaceAllForce] replaceAllForce(map) instead. */ @Synchronized - @Throws(IllegalArgumentException::class) + @Throws(StateException::class) fun replaceAll(hashMap: Map?) { if (hashMap == null) { throw NullPointerException("hashMap") } val biMap = LockFreeIntBiMap() - try { - biMap.putAll(hashMap) - } - catch (e: IllegalArgumentException) { - // do nothing if there is an exception - throw e - } + biMap.putAll(hashMap) // only if there are no problems with the creation of the new bimap. forwardHashMap.clear() @@ -166,11 +160,11 @@ class LockFreeIntBiMap : MutableMap, Cloneable, Serializable { * (A null return can also indicate that the map * previously associated null with key.) * - * @throws IllegalArgumentException if the given value is already bound to a different key in this bimap. The bimap will remain + * @throws StateException if the given value is already bound to a different key in this bimap. The bimap will remain * unmodified in this event. To avoid this exception, call [.putForce] putForce(K, V) instead. */ @Synchronized - @Throws(IllegalArgumentException::class) + @Throws(StateException::class) override fun put(key: Int, value: V): V? { val prevForwardValue = forwardHashMap.put(key, value) if (prevForwardValue != null) { @@ -188,7 +182,8 @@ class LockFreeIntBiMap : MutableMap, Cloneable, Serializable { forwardHashMap.remove(key) } reverseHashMap.put(value, prevReverseValue) - throw java.lang.IllegalArgumentException("Value already exists. Keys and values must both be unique!") + + throw StateException("Value already exists. Keys and values must both be unique!") } return prevForwardValue @@ -233,25 +228,19 @@ class LockFreeIntBiMap : MutableMap, Cloneable, Serializable { * * @throws NullPointerException if the specified map is null * - * @throws IllegalArgumentException if the given value is already bound to a different key in this bimap. The bimap will remain + * @throws StateException if the given value is already bound to a different key in this bimap. The bimap will remain * unmodified in this event. To avoid this exception, call [.putAllForce] putAllForce(K, V) instead. */ @Synchronized - @Throws(IllegalArgumentException::class) + @Throws(StateException::class) override fun putAll(from: Map) { val biMap = LockFreeIntBiMap() - try { - for ((key, value) in from) { - biMap.put(key, value) + for ((key, value) in from) { + biMap.put(key, value) - // we have to verify that the keys/values between the bimaps are unique - require(!forwardHashMap.containsKey(key)) { "Key already exists. Keys and values must both be unique!" } - require(!reverseHashMap.containsKey(value)) { "Value already exists. Keys and values must both be unique!" } - } - } - catch (e: IllegalArgumentException) { - // do nothing if there is an exception - throw e + // we have to verify that the keys/values between the bimaps are unique + if (forwardHashMap.containsKey(key)) { throw StateException("Key already exists. Keys and values must both be unique!") } + if (reverseHashMap.containsKey(value)) { throw StateException("Value already exists. Keys and values must both be unique!") } } // only if there are no problems with the creation of the new bimap AND the uniqueness constrain is guaranteed diff --git a/src/dorkbox/collections/LockFreeIntMap.kt b/src/dorkbox/collections/LockFreeIntMap.kt index 5c36942..b448bc1 100644 --- a/src/dorkbox/collections/LockFreeIntMap.kt +++ b/src/dorkbox/collections/LockFreeIntMap.kt @@ -69,7 +69,7 @@ class LockFreeIntMap : MutableMap, Cloneable, Serializable { * * @param initialCapacity the initial capacity. * - * @throws IllegalArgumentException if the initial capacity is negative. + * @throws StateException if the initial capacity is negative. */ constructor(initialCapacity: Int) { hashMap = IntMap(initialCapacity) @@ -82,7 +82,7 @@ class LockFreeIntMap : MutableMap, Cloneable, Serializable { * @param initialCapacity the initial capacity * @param loadFactor the load factor * - * @throws IllegalArgumentException if the initial capacity is negative + * @throws StateException if the initial capacity is negative * or the load factor is nonpositive */ constructor(initialCapacity: Int, loadFactor: Float) { diff --git a/src/dorkbox/collections/LockFreeIntStringMap.kt b/src/dorkbox/collections/LockFreeIntStringMap.kt index d05b434..b7a9317 100644 --- a/src/dorkbox/collections/LockFreeIntStringMap.kt +++ b/src/dorkbox/collections/LockFreeIntStringMap.kt @@ -58,7 +58,7 @@ class LockFreeIntStringMap : MutableMap, Cloneable, Serializable { * * @param initialCapacity the initial capacity. * - * @throws IllegalArgumentException if the initial capacity is negative. + * @throws StateException if the initial capacity is negative. */ constructor(initialCapacity: Int) { hashMap = IntMap(initialCapacity) @@ -92,7 +92,7 @@ class LockFreeIntStringMap : MutableMap, Cloneable, Serializable { * @param initialCapacity the initial capacity * @param loadFactor the load factor * - * @throws IllegalArgumentException if the initial capacity is negative + * @throws StateException if the initial capacity is negative * or the load factor is nonpositive */ constructor(initialCapacity: Int, loadFactor: Float) { diff --git a/src/dorkbox/collections/LockFreeObjectBiMap.kt b/src/dorkbox/collections/LockFreeObjectBiMap.kt index a7d9f4c..6ca1f6c 100644 --- a/src/dorkbox/collections/LockFreeObjectBiMap.kt +++ b/src/dorkbox/collections/LockFreeObjectBiMap.kt @@ -98,23 +98,17 @@ class LockFreeObjectBiMap : MutableMap, Cloneable, Seriali * * @throws NullPointerException if the specified map is null * - * @throws IllegalArgumentException if a given value in the map is already bound to a different key in this bimap. The bimap will remain + * @throws StateException if a given value in the map is already bound to a different key in this bimap. The bimap will remain * unmodified in this event. To avoid this exception, call [.replaceAllForce] replaceAllForce(map) instead. */ @Synchronized - @Throws(IllegalArgumentException::class) + @Throws(StateException::class) fun replaceAll(hashMap: Map?) { if (hashMap == null) { throw NullPointerException("hashMap") } val biMap = LockFreeObjectBiMap() - try { - biMap.putAll(hashMap) - } - catch (e: IllegalArgumentException) { - // do nothing if there is an exception - throw e - } + biMap.putAll(hashMap) // only if there are no problems with the creation of the new bimap. forwardHashMap.clear() @@ -161,16 +155,17 @@ class LockFreeObjectBiMap : MutableMap, Cloneable, Seriali * (A null return can also indicate that the map * previously associated null with key.) * - * @throws IllegalArgumentException if the given value is already bound to a different key in this bimap. The bimap will remain + * @throws StateException if the given value is already bound to a different key in this bimap. The bimap will remain * unmodified in this event. To avoid this exception, call [.putForce] putForce(K, V) instead. */ @Synchronized - @Throws(IllegalArgumentException::class) + @Throws(StateException::class) override fun put(key: K, value: V): V? { val prevForwardValue = forwardHashMap.put(key, value) if (prevForwardValue != null) { reverseHashMap.remove(prevForwardValue) } + val prevReverseValue = reverseHashMap.put(value, key) if (prevReverseValue != null) { // put the old value back @@ -181,7 +176,7 @@ class LockFreeObjectBiMap : MutableMap, Cloneable, Seriali forwardHashMap.remove(key) } reverseHashMap[value] = prevReverseValue - throw IllegalArgumentException("Value already exists. Keys and values must both be unique!") + throw StateException("Value already exists. Keys and values must both be unique!") } return prevForwardValue } @@ -222,19 +217,19 @@ class LockFreeObjectBiMap : MutableMap, Cloneable, Seriali * * @throws NullPointerException if the specified map is null * - * @throws IllegalArgumentException if the given value is already bound to a different key in this bimap. The bimap will remain + * @throws StateException if the given value is already bound to a different key in this bimap. The bimap will remain * unmodified in this event. To avoid this exception, call [.putAllForce] putAllForce(K, V) instead. */ @Synchronized - @Throws(IllegalArgumentException::class) + @Throws(StateException::class) override fun putAll(from: Map) { val biMap = LockFreeObjectBiMap() for ((key, value) in from) { biMap.put(key, value) // we have to verify that the keys/values between the bimaps are unique - require(!forwardHashMap.containsKey(key)) { "Key already exists. Keys and values must both be unique!" } - require(!reverseHashMap.containsKey(value)) { "Value already exists. Keys and values must both be unique!" } + if (forwardHashMap.containsKey(key)) { throw StateException("Key already exists. Keys and values must both be unique!") } + if (reverseHashMap.containsKey(value)) { throw StateException("Value already exists. Keys and values must both be unique!") } } diff --git a/src/dorkbox/collections/LockFreeObjectIntBiMap.kt b/src/dorkbox/collections/LockFreeObjectIntBiMap.kt index 5638926..fcfa85e 100644 --- a/src/dorkbox/collections/LockFreeObjectIntBiMap.kt +++ b/src/dorkbox/collections/LockFreeObjectIntBiMap.kt @@ -104,23 +104,17 @@ class LockFreeObjectIntBiMap : MutableMap, Cloneable, Serializab * * @throws NullPointerException if the specified map is null * - * @throws IllegalArgumentException if a given value in the map is already bound to a different key in this bimap. The bimap will remain + * @throws StateException if a given value in the map is already bound to a different key in this bimap. The bimap will remain * unmodified in this event. To avoid this exception, call [.replaceAllForce] replaceAllForce(map) instead. */ @Synchronized - @Throws(IllegalArgumentException::class) + @Throws(StateException::class) fun replaceAll(hashMap: Map?) { if (hashMap == null) { throw NullPointerException("hashMap") } val biMap = LockFreeObjectIntBiMap() - try { - biMap.putAll(hashMap) - } - catch (e: IllegalArgumentException) { - // do nothing if there is an exception - throw e - } + biMap.putAll(hashMap) // only if there are no problems with the creation of the new bimap. forwardHashMap.clear() @@ -167,7 +161,7 @@ class LockFreeObjectIntBiMap : MutableMap, Cloneable, Serializab * (A null return can also indicate that the map * previously associated null with key.) * - * @throws IllegalArgumentException if the given value is already bound to a different key in this bimap. The bimap will remain + * @throws StateException if the given value is already bound to a different key in this bimap. The bimap will remain * unmodified in this event. To avoid this exception, call [.putForce] putForce(K, V) instead. */ @Synchronized @@ -189,7 +183,8 @@ class LockFreeObjectIntBiMap : MutableMap, Cloneable, Serializab forwardHashMap.remove(key, defaultReturnValue) } reverseHashMap.put(value, prevReverseValue) - throw java.lang.IllegalArgumentException("Value already exists. Keys and values must both be unique!") + + throw StateException("Value already exists. Keys and values must both be unique!") } return prevForwardValue @@ -237,27 +232,21 @@ class LockFreeObjectIntBiMap : MutableMap, Cloneable, Serializab * * @throws NullPointerException if the specified map is null * - * @throws IllegalArgumentException if the given value is already bound to a different key in this bimap. The bimap will remain + * @throws StateException if the given value is already bound to a different key in this bimap. The bimap will remain * unmodified in this event. To avoid this exception, call [.putAllForce] putAllForce(K, V) instead. */ @Synchronized - @Throws(IllegalArgumentException::class) override fun putAll(from: Map) { val biMap = LockFreeObjectIntBiMap() - try { - for ((key, value) in from) { - biMap.put(key, value) + for ((key, value) in from) { + biMap.put(key, value) - // we have to verify that the keys/values between the bimaps are unique - require(!forwardHashMap.containsKey(key)) { "Key already exists. Keys and values must both be unique!" } - require(!reverseHashMap.containsKey(value)) { "Value already exists. Keys and values must both be unique!" } - } - } - catch (e: IllegalArgumentException) { - // do nothing if there is an exception - throw e + // we have to verify that the keys/values between the bimaps are unique + if (forwardHashMap.containsKey(key)) { throw StateException("Key already exists. Keys and values must both be unique!") } + if (reverseHashMap.containsKey(value)) { throw StateException("Value already exists. Keys and values must both be unique!") } } + // only if there are no problems with the creation of the new bimap AND the uniqueness constrain is guaranteed forwardHashMap.putAll(biMap.forwardHashMap) reverseHashMap.putAll(biMap.reverseHashMap) diff --git a/src/dorkbox/collections/LockFreeObjectIntMap.kt b/src/dorkbox/collections/LockFreeObjectIntMap.kt index 38a9d1a..fe62790 100644 --- a/src/dorkbox/collections/LockFreeObjectIntMap.kt +++ b/src/dorkbox/collections/LockFreeObjectIntMap.kt @@ -69,7 +69,7 @@ class LockFreeObjectIntMap : MutableMap, Cloneable, Serializable * * @param initialCapacity the initial capacity. * - * @throws IllegalArgumentException if the initial capacity is negative. + * @throws StateException if the initial capacity is negative. */ constructor(initialCapacity: Int) { hashMap = ObjectIntMap(initialCapacity) @@ -82,7 +82,7 @@ class LockFreeObjectIntMap : MutableMap, Cloneable, Serializable * @param initialCapacity the initial capacity * @param loadFactor the load factor * - * @throws IllegalArgumentException if the initial capacity is negative + * @throws StateException if the initial capacity is negative * or the load factor is nonpositive */ constructor(initialCapacity: Int, loadFactor: Float) { diff --git a/src/dorkbox/collections/LockFreeObjectMap.kt b/src/dorkbox/collections/LockFreeObjectMap.kt index ab85e12..493ec1d 100644 --- a/src/dorkbox/collections/LockFreeObjectMap.kt +++ b/src/dorkbox/collections/LockFreeObjectMap.kt @@ -69,7 +69,7 @@ class LockFreeObjectMap : MutableMap, Cloneable, Serializable { * * @param initialCapacity the initial capacity. * - * @throws IllegalArgumentException if the initial capacity is negative. + * @throws StateException if the initial capacity is negative. */ constructor(initialCapacity: Int) { hashMap = ObjectMap(initialCapacity) @@ -82,7 +82,7 @@ class LockFreeObjectMap : MutableMap, Cloneable, Serializable { * @param initialCapacity the initial capacity * @param loadFactor the load factor * - * @throws IllegalArgumentException if the initial capacity is negative + * @throws StateException if the initial capacity is negative * or the load factor is nonpositive */ constructor(initialCapacity: Int, loadFactor: Float) { diff --git a/src/dorkbox/collections/LongMap.kt b/src/dorkbox/collections/LongMap.kt index 3d000e3..2191bd3 100644 --- a/src/dorkbox/collections/LongMap.kt +++ b/src/dorkbox/collections/LongMap.kt @@ -115,7 +115,7 @@ class LongMap : MutableMap { * @param loadFactor The loadfactor used to determine backing array growth */ constructor(initialCapacity: Int = 51, loadFactor: Float = 0.8f) { - require(!(loadFactor <= 0f || loadFactor >= 1f)) { "loadFactor must be > 0 and < 1: $loadFactor" } + if ((loadFactor <= 0f || loadFactor >= 1f)) { throw StateException("loadFactor must be > 0 and < 1: $loadFactor") } this.loadFactor = loadFactor val tableSize = tableSize(initialCapacity, loadFactor) @@ -307,7 +307,8 @@ class LongMap : MutableMap { * instead. */ fun shrink(maximumCapacity: Int) { - require(maximumCapacity >= 0) { "maximumCapacity must be >= 0: $maximumCapacity" } + if (maximumCapacity < 0) { throw StateException("maximumCapacity must be >= 0: $maximumCapacity") } + val tableSize = tableSize(maximumCapacity, loadFactor) if (keyTable.size > tableSize) resize(tableSize) } diff --git a/src/dorkbox/collections/LongSet.kt b/src/dorkbox/collections/LongSet.kt index c86ee8d..6ca55d3 100644 --- a/src/dorkbox/collections/LongSet.kt +++ b/src/dorkbox/collections/LongSet.kt @@ -110,7 +110,8 @@ class LongSet: MutableSet { * @param loadFactor The loadfactor used to determine backing array growth */ constructor(initialCapacity: Int = 51, loadFactor: Float = 0.8f) { - require(!(loadFactor <= 0f || loadFactor >= 1f)) { "loadFactor must be > 0 and < 1: $loadFactor" } + if ((loadFactor <= 0f || loadFactor >= 1f)) { throw StateException("loadFactor must be > 0 and < 1: $loadFactor") } + this.loadFactor = loadFactor val tableSize = tableSize(initialCapacity, loadFactor) threshold = (tableSize * loadFactor).toInt() @@ -203,7 +204,8 @@ class LongSet: MutableSet { } fun addAll(array: LongArray, offset: Int, length: Int) { - require(offset + length <= array.size) { "offset + length must be <= size: $offset + $length <= ${array.size}" } + if (offset + length > array.size) { throw StateException("offset + length must be <= size: $offset + $length <= ${array.size}") } + ensureCapacity(length) var i = offset @@ -293,7 +295,8 @@ class LongSet: MutableSet { * instead. */ fun shrink(maximumCapacity: Int) { - require(maximumCapacity >= 0) { "maximumCapacity must be >= 0: $maximumCapacity" } + if (maximumCapacity < 0) { throw StateException("maximumCapacity must be >= 0: $maximumCapacity") } + val tableSize = tableSize(maximumCapacity, loadFactor) if (keyTable.size > tableSize) resize(tableSize) } diff --git a/src/dorkbox/collections/ObjectFloatMap.kt b/src/dorkbox/collections/ObjectFloatMap.kt index 2e43cd3..8f51a72 100644 --- a/src/dorkbox/collections/ObjectFloatMap.kt +++ b/src/dorkbox/collections/ObjectFloatMap.kt @@ -126,7 +126,7 @@ open class ObjectFloatMap : MutableMap { * @param loadFactor The loadfactor used to determine backing array growth */ constructor(initialCapacity: Int = 51, loadFactor: Float = 0.8f) { - require(!(loadFactor <= 0f || loadFactor >= 1f)) { "loadFactor must be > 0 and < 1: $loadFactor" } + if ((loadFactor <= 0f || loadFactor >= 1f)) { throw StateException("loadFactor must be > 0 and < 1: $loadFactor") } this.loadFactor = loadFactor val tableSize = tableSize(initialCapacity, loadFactor) @@ -386,7 +386,8 @@ open class ObjectFloatMap : MutableMap { * instead. */ open fun shrink(maximumCapacity: Int) { - require(maximumCapacity >= 0) { "maximumCapacity must be >= 0: $maximumCapacity" } + if (maximumCapacity < 0) { throw StateException("maximumCapacity must be >= 0: $maximumCapacity") } + val tableSize = tableSize(maximumCapacity, loadFactor) if (keyTable.size > tableSize) resize(tableSize) } diff --git a/src/dorkbox/collections/ObjectIntMap.kt b/src/dorkbox/collections/ObjectIntMap.kt index 8bbe2d5..ab2d211 100644 --- a/src/dorkbox/collections/ObjectIntMap.kt +++ b/src/dorkbox/collections/ObjectIntMap.kt @@ -36,7 +36,6 @@ package dorkbox.collections import dorkbox.collections.Collections.allocateIterators import dorkbox.collections.ObjectSet.Companion.tableSize -import java.lang.IllegalStateException import java.util.* /** @@ -123,7 +122,7 @@ open class ObjectIntMap : MutableMap { * @param loadFactor The loadfactor used to determine backing array growth */ constructor(initialCapacity: Int = 51, loadFactor: Float = 0.8f) { - require(!(loadFactor <= 0f || loadFactor >= 1f)) { "loadFactor must be > 0 and < 1: $loadFactor" } + if ((loadFactor <= 0f || loadFactor >= 1f)) { throw StateException("loadFactor must be > 0 and < 1: $loadFactor") } this.loadFactor = loadFactor val tableSize = tableSize(initialCapacity, loadFactor) @@ -329,7 +328,8 @@ open class ObjectIntMap : MutableMap { * instead. */ open fun shrink(maximumCapacity: Int) { - require(maximumCapacity >= 0) { "maximumCapacity must be >= 0: $maximumCapacity" } + if (maximumCapacity < 0) { throw StateException("maximumCapacity must be >= 0: $maximumCapacity") } + val tableSize = tableSize(maximumCapacity, loadFactor) if (keyTable.size > tableSize) resize(tableSize) } diff --git a/src/dorkbox/collections/ObjectMap.kt b/src/dorkbox/collections/ObjectMap.kt index ddd87b9..d92b00b 100644 --- a/src/dorkbox/collections/ObjectMap.kt +++ b/src/dorkbox/collections/ObjectMap.kt @@ -126,7 +126,7 @@ open class ObjectMap : MutableMap { * @param loadFactor The loadfactor used to determine backing array growth */ constructor(initialCapacity: Int = 51, loadFactor: Float = 0.8f) { - require(!(loadFactor <= 0f || loadFactor >= 1f)) { "loadFactor must be > 0 and < 1: $loadFactor" } + if ((loadFactor <= 0f || loadFactor >= 1f)) { throw StateException("loadFactor must be > 0 and < 1: $loadFactor") } this.loadFactor = loadFactor val tableSize = tableSize(initialCapacity, loadFactor) @@ -313,7 +313,8 @@ open class ObjectMap : MutableMap { * instead. */ open fun shrink(maximumCapacity: Int) { - require(maximumCapacity >= 0) { "maximumCapacity must be >= 0: $maximumCapacity" } + if (maximumCapacity < 0) { throw StateException("maximumCapacity must be >= 0: $maximumCapacity") } + val tableSize = tableSize(maximumCapacity, loadFactor) if (keyTable.size > tableSize) resize(tableSize) } diff --git a/src/dorkbox/collections/ObjectSet.kt b/src/dorkbox/collections/ObjectSet.kt index 4966e8e..1a4638f 100644 --- a/src/dorkbox/collections/ObjectSet.kt +++ b/src/dorkbox/collections/ObjectSet.kt @@ -68,13 +68,13 @@ open class ObjectSet : MutableSet { } fun tableSize(capacity: Int, loadFactor: Float): Int { - require(capacity >= 0) { "capacity must be >= 0: $capacity" } + if (capacity < 0) { throw StateException("capacity must be >= 0: $capacity") } + val tableSize: Int = Collections.nextPowerOfTwo( - max( - 2.0, ceil((capacity / loadFactor).toDouble()).toInt().toDouble() - ).toInt() + max(2.0, ceil((capacity / loadFactor).toDouble()).toInt().toDouble()).toInt() ) - require(tableSize <= 1 shl 30) { "The required capacity is too large: $capacity" } + + if (tableSize > 1 shl 30) { throw StateException("The required capacity is too large: $capacity") } return tableSize } } @@ -123,7 +123,8 @@ open class ObjectSet : MutableSet { * @param loadFactor The loadfactor used to determine backing array growth */ constructor(initialCapacity: Int = 51, loadFactor: Float = 0.8f) { - require(!(loadFactor <= 0f || loadFactor >= 1f)) { "loadFactor must be > 0 and < 1: $loadFactor" } + if ((loadFactor <= 0f || loadFactor >= 1f)) { throw StateException("loadFactor must be > 0 and < 1: $loadFactor") } + this.loadFactor = loadFactor val tableSize = tableSize(initialCapacity, loadFactor) threshold = (tableSize * loadFactor).toInt() @@ -205,7 +206,8 @@ open class ObjectSet : MutableSet { } fun addAll(array: Array, offset: Int, length: Int) { - require(offset + length <= array.size) { "offset + length must be <= size: " + offset + " + " + length + " <= " + array.size } + if (offset + length > array.size) { throw StateException("offset + length must be <= size: $offset + $length <= ${array.size}") } + addAll(array, offset, length) } @@ -320,7 +322,8 @@ open class ObjectSet : MutableSet { * instead. */ fun shrink(maximumCapacity: Int) { - require(maximumCapacity >= 0) { "maximumCapacity must be >= 0: $maximumCapacity" } + if (maximumCapacity < 0) { throw StateException("maximumCapacity must be >= 0: $maximumCapacity") } + val tableSize = tableSize(maximumCapacity, loadFactor) if (keyTable.size > tableSize) resize(tableSize) } diff --git a/src/dorkbox/collections/StateException.kt b/src/dorkbox/collections/StateException.kt new file mode 100644 index 0000000..16fd985 --- /dev/null +++ b/src/dorkbox/collections/StateException.kt @@ -0,0 +1,23 @@ +/* + * Copyright 2023 dorkbox, llc + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dorkbox.collections + +class StateException: Exception { + + constructor(message: String) : super(message) + +}