No longer throws RuntimeException (IllegalArgumentException), but now StateException
parent
5e00bba892
commit
a1a4cfb88f
|
@ -193,7 +193,7 @@ class ArrayMap<K: Any, V> : MutableMap<K, V?>{
|
|||
}
|
||||
|
||||
fun putAll(map: ArrayMap<out K, out V>, 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<K: Any, V> : MutableMap<K, V?>{
|
|||
* 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()
|
||||
|
|
|
@ -83,7 +83,7 @@ class BinarySearch<T>(private val eval: Evaluator<T>, 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
|
||||
}
|
||||
|
|
|
@ -165,7 +165,8 @@ class ExpandingArray<T> : MutableIterable<T> {
|
|||
}
|
||||
|
||||
fun addAll(array: ExpandingArray<out T>, 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<T>, start, count)
|
||||
}
|
||||
|
@ -503,7 +504,8 @@ class ExpandingArray<T> : MutableIterable<T> {
|
|||
* @return [.items]
|
||||
*/
|
||||
fun ensureCapacity(additionalCapacity: Int): Array<T?> {
|
||||
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<T> : MutableIterable<T> {
|
|||
* 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
|
||||
|
|
|
@ -115,7 +115,7 @@ class IntFloatMap : MutableMap<Int, Float> {
|
|||
* @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<Int, Float> {
|
|||
* 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)
|
||||
}
|
||||
|
|
|
@ -115,7 +115,7 @@ class IntIntMap : MutableMap<Int, Int> {
|
|||
* @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<Int, Int> {
|
|||
* 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)
|
||||
}
|
||||
|
|
|
@ -116,7 +116,7 @@ open class IntMap<V> : MutableMap<Int, V> {
|
|||
* @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<V> : MutableMap<Int, V> {
|
|||
* 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)
|
||||
}
|
||||
|
|
|
@ -110,7 +110,8 @@ class IntSet: MutableSet<Int> {
|
|||
* @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<Int> {
|
|||
}
|
||||
|
||||
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<Int> {
|
|||
* 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)
|
||||
}
|
||||
|
|
|
@ -95,23 +95,17 @@ class LockFreeBiMap<K: Any, V: Any> : MutableMap<K, V>, 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<K, V>?) {
|
||||
if (hashMap == null) {
|
||||
throw NullPointerException("hashMap")
|
||||
}
|
||||
val biMap = LockFreeBiMap<K, V>()
|
||||
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<K: Any, V: Any> : MutableMap<K, V>, Cloneable, Serializable
|
|||
* (A <tt>null</tt> return can also indicate that the map
|
||||
* previously associated <tt>null</tt> with <tt>key</tt>.)
|
||||
*
|
||||
* @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<K: Any, V: Any> : MutableMap<K, V>, 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<K: Any, V: Any> : MutableMap<K, V>, 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<out K, V>) {
|
||||
val biMap = LockFreeBiMap<K, V>()
|
||||
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!") }
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -58,7 +58,7 @@ class LockFreeHashMap<K: Any, V> : MutableMap<K, V>, 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<K: Any, V> : MutableMap<K, V>, 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) {
|
||||
|
|
|
@ -103,23 +103,17 @@ class LockFreeIntBiMap<V: Any> : MutableMap<Int, V>, 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<Int, V>?) {
|
||||
if (hashMap == null) {
|
||||
throw NullPointerException("hashMap")
|
||||
}
|
||||
val biMap = LockFreeIntBiMap<V>()
|
||||
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<V: Any> : MutableMap<Int, V>, Cloneable, Serializable {
|
|||
* (A <tt>null</tt> return can also indicate that the map
|
||||
* previously associated <tt>null</tt> with <tt>key</tt>.)
|
||||
*
|
||||
* @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<V: Any> : MutableMap<Int, V>, 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<V: Any> : MutableMap<Int, V>, 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<out Int, V>) {
|
||||
val biMap = LockFreeIntBiMap<V>()
|
||||
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
|
||||
|
|
|
@ -69,7 +69,7 @@ class LockFreeIntMap<V> : MutableMap<Int, V>, 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<V> : MutableMap<Int, V>, 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) {
|
||||
|
|
|
@ -58,7 +58,7 @@ class LockFreeIntStringMap : MutableMap<Int, String?>, 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<Int, String?>, 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) {
|
||||
|
|
|
@ -98,23 +98,17 @@ class LockFreeObjectBiMap<K: Any, V: Any> : MutableMap<K, V>, 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<K, V>?) {
|
||||
if (hashMap == null) {
|
||||
throw NullPointerException("hashMap")
|
||||
}
|
||||
val biMap = LockFreeObjectBiMap<K, V>()
|
||||
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<K: Any, V: Any> : MutableMap<K, V>, Cloneable, Seriali
|
|||
* (A <tt>null</tt> return can also indicate that the map
|
||||
* previously associated <tt>null</tt> with <tt>key</tt>.)
|
||||
*
|
||||
* @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<K: Any, V: Any> : MutableMap<K, V>, 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<K: Any, V: Any> : MutableMap<K, V>, 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<out K, V>) {
|
||||
val biMap = LockFreeObjectBiMap<K, V>()
|
||||
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!") }
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -104,23 +104,17 @@ class LockFreeObjectIntBiMap<K: Any> : MutableMap<K, Int>, 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<K, Int>?) {
|
||||
if (hashMap == null) {
|
||||
throw NullPointerException("hashMap")
|
||||
}
|
||||
val biMap = LockFreeObjectIntBiMap<K>()
|
||||
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<K: Any> : MutableMap<K, Int>, Cloneable, Serializab
|
|||
* (A <tt>null</tt> return can also indicate that the map
|
||||
* previously associated <tt>null</tt> with <tt>key</tt>.)
|
||||
*
|
||||
* @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<K: Any> : MutableMap<K, Int>, 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<K: Any> : MutableMap<K, Int>, 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<out K, Int>) {
|
||||
val biMap = LockFreeObjectIntBiMap<K>()
|
||||
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)
|
||||
|
|
|
@ -69,7 +69,7 @@ class LockFreeObjectIntMap<K: Any> : MutableMap<K, Int>, 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<K: Any> : MutableMap<K, Int>, 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) {
|
||||
|
|
|
@ -69,7 +69,7 @@ class LockFreeObjectMap<K: Any, V> : MutableMap<K, V>, 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<K: Any, V> : MutableMap<K, V>, 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) {
|
||||
|
|
|
@ -115,7 +115,7 @@ class LongMap<V> : MutableMap<Long, V?> {
|
|||
* @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<V> : MutableMap<Long, V?> {
|
|||
* 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)
|
||||
}
|
||||
|
|
|
@ -110,7 +110,8 @@ class LongSet: MutableSet<Long> {
|
|||
* @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<Long> {
|
|||
}
|
||||
|
||||
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<Long> {
|
|||
* 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)
|
||||
}
|
||||
|
|
|
@ -126,7 +126,7 @@ open class ObjectFloatMap<K: Any> : MutableMap<K, Float> {
|
|||
* @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<K: Any> : MutableMap<K, Float> {
|
|||
* 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)
|
||||
}
|
||||
|
|
|
@ -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<K: Any> : MutableMap<K, Int> {
|
|||
* @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<K: Any> : MutableMap<K, Int> {
|
|||
* 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)
|
||||
}
|
||||
|
|
|
@ -126,7 +126,7 @@ open class ObjectMap<K: Any, V> : MutableMap<K, V?> {
|
|||
* @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<K: Any, V> : MutableMap<K, V?> {
|
|||
* 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)
|
||||
}
|
||||
|
|
|
@ -68,13 +68,13 @@ open class ObjectSet<T: Any> : MutableSet<T> {
|
|||
}
|
||||
|
||||
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<T: Any> : MutableSet<T> {
|
|||
* @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<T: Any> : MutableSet<T> {
|
|||
}
|
||||
|
||||
fun addAll(array: Array<out T>, 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<T: Any> : MutableSet<T> {
|
|||
* 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)
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
||||
}
|
Loading…
Reference in New Issue