To avoid name conflicts, move dynamic synchable group map implementation to asMap property
This commit is contained in:
parent
1cfa2be1dd
commit
77443ee801
@ -50,7 +50,7 @@ class DynamicSynchableGroup<T : Any>(
|
||||
* first-time networking of [T] to remote
|
||||
*/
|
||||
private val writer: T.(RegistryFriendlyByteBuf) -> Unit = {},
|
||||
) : ISynchable, ReferenceSet<T>, Int2ReferenceMap<T> {
|
||||
) : ISynchable, ReferenceSet<T> {
|
||||
private inner class RemoteState(val listener: Runnable) : IRemoteState {
|
||||
private inner class RemoteSlot(val slot: Slot<T>, fromConstructor: Boolean) : Runnable, Closeable {
|
||||
val remoteState = synchable(slot.value).createRemoteState(this)
|
||||
@ -367,315 +367,341 @@ class DynamicSynchableGroup<T : Any>(
|
||||
return any
|
||||
}
|
||||
|
||||
override fun put(key: Int, value: T): T? {
|
||||
val slot = Slot(value, key)
|
||||
val oldSlot = id2slot.put(key, slot)
|
||||
/**
|
||||
* Representation of this synchable group as an [Int2ReferenceMap]. Changes made to [DynamicSynchableGroup] are reflected in this map
|
||||
* and vice versa. Entries can be put at arbitrary keys, but negative keys should be avoided, since they are not efficiently
|
||||
* networked, and hence will create a lot of network traffic if synchables with negative keys get frequently updated.
|
||||
*/
|
||||
val asMap: Int2ReferenceMap<T> by lazy {
|
||||
object : Int2ReferenceMap<T> {
|
||||
override fun isEmpty(): Boolean {
|
||||
return this@DynamicSynchableGroup.isEmpty()
|
||||
}
|
||||
|
||||
if (oldSlot?.value === value)
|
||||
return value
|
||||
override fun remove(key: Int): T? {
|
||||
val slot = id2slot.remove(key) ?: return null
|
||||
removeBySlot(slot)
|
||||
return slot.value
|
||||
}
|
||||
|
||||
if (oldSlot != null) {
|
||||
remoteStates.forEach { it.remove(oldSlot) }
|
||||
value2slot.remove(oldSlot.value)
|
||||
} else {
|
||||
idAllocator.allocate(key)
|
||||
}
|
||||
|
||||
value2slot[value] = slot
|
||||
remoteStates.forEach { it.add(slot) }
|
||||
|
||||
return oldSlot?.value
|
||||
}
|
||||
|
||||
override fun get(key: Int): T? {
|
||||
return id2slot.get(key)?.value ?: defaultReturnValue
|
||||
}
|
||||
|
||||
override fun containsKey(key: Int): Boolean {
|
||||
return id2slot.containsKey(key)
|
||||
}
|
||||
|
||||
override fun defaultReturnValue(rv: T?) {
|
||||
defaultReturnValue = rv
|
||||
}
|
||||
|
||||
override fun defaultReturnValue(): T? {
|
||||
return defaultReturnValue
|
||||
}
|
||||
|
||||
override fun putAll(from: Map<out Int, T>) {
|
||||
from.forEach { (k, v) ->
|
||||
put(k, v)
|
||||
}
|
||||
}
|
||||
|
||||
override fun containsValue(value: T): Boolean {
|
||||
return value2slot.containsKey(value)
|
||||
}
|
||||
|
||||
private val entrySet: ObjectSet<Int2ReferenceMap.Entry<T>> by lazy(LazyThreadSafetyMode.PUBLICATION) {
|
||||
object : ObjectSet<Int2ReferenceMap.Entry<T>> {
|
||||
inner class Entry(private val ikey: Int) : Int2ReferenceMap.Entry<T> {
|
||||
override val value: T
|
||||
get() = id2slot[ikey]?.value ?: throw NoSuchElementException()
|
||||
|
||||
override fun setValue(newValue: T): T? {
|
||||
return put(ikey, newValue)
|
||||
}
|
||||
|
||||
override fun getIntKey(): Int {
|
||||
return ikey
|
||||
}
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
return this === other || other is Int2ReferenceMap.Entry<*> && other.intKey == ikey && other.value === id2slot[ikey]?.value
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
return ikey * 31 + (id2slot[ikey] as Slot<T>?).hashCode()
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
||||
return "Map.Entry[$ikey, ${id2slot[ikey]?.value}]"
|
||||
}
|
||||
override fun getOrDefault(key: Int, defaultValue: T): T {
|
||||
return super.getOrDefault(key, defaultValue)
|
||||
}
|
||||
|
||||
override val size: Int
|
||||
get() = id2slot.size
|
||||
get() = this@DynamicSynchableGroup.size
|
||||
|
||||
override fun add(element: Int2ReferenceMap.Entry<T>): Boolean {
|
||||
return put(element.intKey, element.value) != null
|
||||
}
|
||||
override fun put(key: Int, value: T): T? {
|
||||
val slot = Slot(value, key)
|
||||
val oldSlot = id2slot.put(key, slot)
|
||||
|
||||
override fun addAll(elements: Collection<Int2ReferenceMap.Entry<T>>): Boolean {
|
||||
var any = false
|
||||
elements.forEach { any = add(it) || any }
|
||||
return any
|
||||
}
|
||||
if (oldSlot?.value === value)
|
||||
return value
|
||||
|
||||
override fun clear() {
|
||||
this@DynamicSynchableGroup.clear()
|
||||
}
|
||||
|
||||
override fun iterator(): ObjectIterator<Int2ReferenceMap.Entry<T>> {
|
||||
return object : ObjectIterator<Int2ReferenceMap.Entry<T>> {
|
||||
private val parent = id2slot.int2ReferenceEntrySet().iterator()
|
||||
private var last: Slot<T>? = null
|
||||
|
||||
override fun hasNext(): Boolean {
|
||||
return parent.hasNext()
|
||||
}
|
||||
|
||||
override fun remove() {
|
||||
if (last == null)
|
||||
throw NoSuchElementException()
|
||||
|
||||
parent.remove()
|
||||
removeBySlot(last!!)
|
||||
last = null
|
||||
}
|
||||
|
||||
override fun next(): Int2ReferenceMap.Entry<T> {
|
||||
val value = parent.next()
|
||||
last = value.value
|
||||
return Entry(value.intKey)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun remove(element: Int2ReferenceMap.Entry<T>): Boolean {
|
||||
val slot = id2slot.get(element.intKey)
|
||||
|
||||
if (slot?.value === element.value) {
|
||||
this@DynamicSynchableGroup.removeBySlot(slot)
|
||||
return true
|
||||
if (oldSlot != null) {
|
||||
remoteStates.forEach { it.remove(oldSlot) }
|
||||
value2slot.remove(oldSlot.value)
|
||||
} else {
|
||||
idAllocator.allocate(key)
|
||||
}
|
||||
|
||||
return false
|
||||
value2slot[value] = slot
|
||||
remoteStates.forEach { it.add(slot) }
|
||||
|
||||
return oldSlot?.value
|
||||
}
|
||||
|
||||
override fun removeAll(elements: Collection<Int2ReferenceMap.Entry<T>>): Boolean {
|
||||
var any = false
|
||||
elements.forEach { any = remove(it) || any }
|
||||
return any
|
||||
override fun get(key: Int): T? {
|
||||
return id2slot.get(key)?.value ?: defaultReturnValue
|
||||
}
|
||||
|
||||
override fun retainAll(elements: Collection<Int2ReferenceMap.Entry<T>>): Boolean {
|
||||
if (elements.isEmpty()) {
|
||||
val isNotEmpty = id2slot.isNotEmpty()
|
||||
this@DynamicSynchableGroup.clear()
|
||||
return isNotEmpty
|
||||
}
|
||||
|
||||
var any = false
|
||||
val itr = id2slot.int2ReferenceEntrySet().iterator()
|
||||
|
||||
for (entry in itr) {
|
||||
if (elements.none { it.intKey == entry.intKey && it.value === entry.value.value }) {
|
||||
any = true
|
||||
itr.remove()
|
||||
removeBySlot(entry.value)
|
||||
}
|
||||
}
|
||||
|
||||
return any
|
||||
}
|
||||
|
||||
override fun contains(element: Int2ReferenceMap.Entry<T>): Boolean {
|
||||
return id2slot.get(element.intKey)?.value === element.value
|
||||
}
|
||||
|
||||
override fun containsAll(elements: Collection<Int2ReferenceMap.Entry<T>>): Boolean {
|
||||
return elements.all { contains(it) }
|
||||
}
|
||||
|
||||
override fun isEmpty(): Boolean {
|
||||
return id2slot.isEmpty()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun int2ReferenceEntrySet(): ObjectSet<Int2ReferenceMap.Entry<T>> {
|
||||
return entrySet
|
||||
}
|
||||
|
||||
override val keys: IntSet by lazy(LazyThreadSafetyMode.PUBLICATION) {
|
||||
object : IntSet {
|
||||
override fun add(key: Int): Boolean {
|
||||
throw UnsupportedOperationException()
|
||||
}
|
||||
|
||||
override fun addAll(c: IntCollection): Boolean {
|
||||
throw UnsupportedOperationException()
|
||||
}
|
||||
|
||||
override fun addAll(elements: Collection<Int>): Boolean {
|
||||
throw UnsupportedOperationException()
|
||||
}
|
||||
|
||||
override fun clear() {
|
||||
this@DynamicSynchableGroup.clear()
|
||||
}
|
||||
|
||||
override fun iterator(): IntIterator {
|
||||
return object : IntIterator {
|
||||
private val parent = id2slot.keys.iterator()
|
||||
private var last = -1
|
||||
private var hasLast = false
|
||||
|
||||
override fun hasNext(): Boolean {
|
||||
return parent.hasNext()
|
||||
}
|
||||
|
||||
override fun remove() {
|
||||
if (!hasLast)
|
||||
throw NoSuchElementException()
|
||||
|
||||
hasLast = false
|
||||
val slot = id2slot.get(last)
|
||||
parent.remove()
|
||||
removeBySlot(slot)
|
||||
}
|
||||
|
||||
override fun nextInt(): Int {
|
||||
last = parent.nextInt()
|
||||
hasLast = true
|
||||
return last
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun remove(k: Int): Boolean {
|
||||
removeBySlot(id2slot.get(k) ?: return false)
|
||||
return true
|
||||
}
|
||||
|
||||
override fun removeAll(c: IntCollection): Boolean {
|
||||
val itr = c.iterator()
|
||||
var any = false
|
||||
|
||||
while (itr.hasNext()) {
|
||||
any = remove(itr.nextInt()) || any
|
||||
}
|
||||
|
||||
return any
|
||||
}
|
||||
|
||||
override fun removeAll(elements: Collection<Int>): Boolean {
|
||||
val itr = elements.iterator()
|
||||
var any = false
|
||||
|
||||
while (itr.hasNext()) {
|
||||
any = remove(itr.next()) || any
|
||||
}
|
||||
|
||||
return any
|
||||
}
|
||||
|
||||
override fun retainAll(c: IntCollection): Boolean {
|
||||
val itr = id2slot.values.iterator()
|
||||
var any = false
|
||||
|
||||
for (slot in itr) {
|
||||
if (!c.contains(slot.id)) {
|
||||
itr.remove()
|
||||
check(value2slot.remove(slot.value) == slot)
|
||||
remoteStates.forEach { it.remove(slot) }
|
||||
any = true
|
||||
}
|
||||
}
|
||||
|
||||
return any
|
||||
}
|
||||
|
||||
override fun retainAll(elements: Collection<Int>): Boolean {
|
||||
val itr = id2slot.values.iterator()
|
||||
var any = false
|
||||
|
||||
for (slot in itr) {
|
||||
if (!elements.contains(slot.id)) {
|
||||
itr.remove()
|
||||
check(value2slot.remove(slot.value) == slot)
|
||||
remoteStates.forEach { it.remove(slot) }
|
||||
any = true
|
||||
}
|
||||
}
|
||||
|
||||
return any
|
||||
}
|
||||
|
||||
override fun contains(key: Int): Boolean {
|
||||
override fun containsKey(key: Int): Boolean {
|
||||
return id2slot.containsKey(key)
|
||||
}
|
||||
|
||||
override fun containsAll(c: IntCollection): Boolean {
|
||||
return id2slot.keys.containsAll(c)
|
||||
override fun defaultReturnValue(rv: T?) {
|
||||
defaultReturnValue = rv
|
||||
}
|
||||
|
||||
override fun containsAll(elements: Collection<Int>): Boolean {
|
||||
return id2slot.keys.containsAll(elements)
|
||||
override fun defaultReturnValue(): T? {
|
||||
return defaultReturnValue
|
||||
}
|
||||
|
||||
override fun isEmpty(): Boolean {
|
||||
return id2slot.isEmpty()
|
||||
override fun putAll(from: Map<out Int, T>) {
|
||||
from.forEach { (k, v) ->
|
||||
put(k, v)
|
||||
}
|
||||
}
|
||||
|
||||
override fun toArray(a: IntArray?): IntArray {
|
||||
return id2slot.keys.toArray(a)
|
||||
override fun containsValue(value: T): Boolean {
|
||||
return value2slot.containsKey(value)
|
||||
}
|
||||
|
||||
override fun toIntArray(): IntArray {
|
||||
return id2slot.keys.toIntArray()
|
||||
private val entrySet: ObjectSet<Int2ReferenceMap.Entry<T>> by lazy(LazyThreadSafetyMode.PUBLICATION) {
|
||||
object : ObjectSet<Int2ReferenceMap.Entry<T>> {
|
||||
inner class Entry(private val ikey: Int) : Int2ReferenceMap.Entry<T> {
|
||||
override val value: T
|
||||
get() = id2slot[ikey]?.value ?: throw NoSuchElementException()
|
||||
|
||||
override fun setValue(newValue: T): T? {
|
||||
return put(ikey, newValue)
|
||||
}
|
||||
|
||||
override fun getIntKey(): Int {
|
||||
return ikey
|
||||
}
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
return this === other || other is Int2ReferenceMap.Entry<*> && other.intKey == ikey && other.value === id2slot[ikey]?.value
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
return ikey * 31 + (id2slot[ikey] as Slot<T>?).hashCode()
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
||||
return "Map.Entry[$ikey, ${id2slot[ikey]?.value}]"
|
||||
}
|
||||
}
|
||||
|
||||
override val size: Int
|
||||
get() = id2slot.size
|
||||
|
||||
override fun add(element: Int2ReferenceMap.Entry<T>): Boolean {
|
||||
return put(element.intKey, element.value) != null
|
||||
}
|
||||
|
||||
override fun addAll(elements: Collection<Int2ReferenceMap.Entry<T>>): Boolean {
|
||||
var any = false
|
||||
elements.forEach { any = add(it) || any }
|
||||
return any
|
||||
}
|
||||
|
||||
override fun clear() {
|
||||
this@DynamicSynchableGroup.clear()
|
||||
}
|
||||
|
||||
override fun iterator(): ObjectIterator<Int2ReferenceMap.Entry<T>> {
|
||||
return object : ObjectIterator<Int2ReferenceMap.Entry<T>> {
|
||||
private val parent = id2slot.int2ReferenceEntrySet().iterator()
|
||||
private var last: Slot<T>? = null
|
||||
|
||||
override fun hasNext(): Boolean {
|
||||
return parent.hasNext()
|
||||
}
|
||||
|
||||
override fun remove() {
|
||||
if (last == null)
|
||||
throw NoSuchElementException()
|
||||
|
||||
parent.remove()
|
||||
removeBySlot(last!!)
|
||||
last = null
|
||||
}
|
||||
|
||||
override fun next(): Int2ReferenceMap.Entry<T> {
|
||||
val value = parent.next()
|
||||
last = value.value
|
||||
return Entry(value.intKey)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun remove(element: Int2ReferenceMap.Entry<T>): Boolean {
|
||||
val slot = id2slot.get(element.intKey)
|
||||
|
||||
if (slot?.value === element.value) {
|
||||
this@DynamicSynchableGroup.removeBySlot(slot)
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
override fun removeAll(elements: Collection<Int2ReferenceMap.Entry<T>>): Boolean {
|
||||
var any = false
|
||||
elements.forEach { any = remove(it) || any }
|
||||
return any
|
||||
}
|
||||
|
||||
override fun retainAll(elements: Collection<Int2ReferenceMap.Entry<T>>): Boolean {
|
||||
if (elements.isEmpty()) {
|
||||
val isNotEmpty = id2slot.isNotEmpty()
|
||||
this@DynamicSynchableGroup.clear()
|
||||
return isNotEmpty
|
||||
}
|
||||
|
||||
var any = false
|
||||
val itr = id2slot.int2ReferenceEntrySet().iterator()
|
||||
|
||||
for (entry in itr) {
|
||||
if (elements.none { it.intKey == entry.intKey && it.value === entry.value.value }) {
|
||||
any = true
|
||||
itr.remove()
|
||||
removeBySlot(entry.value)
|
||||
}
|
||||
}
|
||||
|
||||
return any
|
||||
}
|
||||
|
||||
override fun contains(element: Int2ReferenceMap.Entry<T>): Boolean {
|
||||
return id2slot.get(element.intKey)?.value === element.value
|
||||
}
|
||||
|
||||
override fun containsAll(elements: Collection<Int2ReferenceMap.Entry<T>>): Boolean {
|
||||
return elements.all { contains(it) }
|
||||
}
|
||||
|
||||
override fun isEmpty(): Boolean {
|
||||
return id2slot.isEmpty()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override val size: Int
|
||||
get() = id2slot.size
|
||||
override fun int2ReferenceEntrySet(): ObjectSet<Int2ReferenceMap.Entry<T>> {
|
||||
return entrySet
|
||||
}
|
||||
|
||||
override val keys: IntSet by lazy(LazyThreadSafetyMode.PUBLICATION) {
|
||||
object : IntSet {
|
||||
override fun add(key: Int): Boolean {
|
||||
throw UnsupportedOperationException()
|
||||
}
|
||||
|
||||
override fun addAll(c: IntCollection): Boolean {
|
||||
throw UnsupportedOperationException()
|
||||
}
|
||||
|
||||
override fun addAll(elements: Collection<Int>): Boolean {
|
||||
throw UnsupportedOperationException()
|
||||
}
|
||||
|
||||
override fun clear() {
|
||||
this@DynamicSynchableGroup.clear()
|
||||
}
|
||||
|
||||
override fun iterator(): IntIterator {
|
||||
return object : IntIterator {
|
||||
private val parent = id2slot.keys.iterator()
|
||||
private var last = -1
|
||||
private var hasLast = false
|
||||
|
||||
override fun hasNext(): Boolean {
|
||||
return parent.hasNext()
|
||||
}
|
||||
|
||||
override fun remove() {
|
||||
if (!hasLast)
|
||||
throw NoSuchElementException()
|
||||
|
||||
hasLast = false
|
||||
val slot = id2slot.get(last)
|
||||
parent.remove()
|
||||
removeBySlot(slot)
|
||||
}
|
||||
|
||||
override fun nextInt(): Int {
|
||||
last = parent.nextInt()
|
||||
hasLast = true
|
||||
return last
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun remove(k: Int): Boolean {
|
||||
removeBySlot(id2slot.get(k) ?: return false)
|
||||
return true
|
||||
}
|
||||
|
||||
override fun removeAll(c: IntCollection): Boolean {
|
||||
val itr = c.iterator()
|
||||
var any = false
|
||||
|
||||
while (itr.hasNext()) {
|
||||
any = remove(itr.nextInt()) || any
|
||||
}
|
||||
|
||||
return any
|
||||
}
|
||||
|
||||
override fun removeAll(elements: Collection<Int>): Boolean {
|
||||
val itr = elements.iterator()
|
||||
var any = false
|
||||
|
||||
while (itr.hasNext()) {
|
||||
any = remove(itr.next()) || any
|
||||
}
|
||||
|
||||
return any
|
||||
}
|
||||
|
||||
override fun retainAll(c: IntCollection): Boolean {
|
||||
val itr = id2slot.values.iterator()
|
||||
var any = false
|
||||
|
||||
for (slot in itr) {
|
||||
if (!c.contains(slot.id)) {
|
||||
itr.remove()
|
||||
check(value2slot.remove(slot.value) == slot)
|
||||
remoteStates.forEach { it.remove(slot) }
|
||||
any = true
|
||||
}
|
||||
}
|
||||
|
||||
return any
|
||||
}
|
||||
|
||||
override fun retainAll(elements: Collection<Int>): Boolean {
|
||||
val itr = id2slot.values.iterator()
|
||||
var any = false
|
||||
|
||||
for (slot in itr) {
|
||||
if (!elements.contains(slot.id)) {
|
||||
itr.remove()
|
||||
check(value2slot.remove(slot.value) == slot)
|
||||
remoteStates.forEach { it.remove(slot) }
|
||||
any = true
|
||||
}
|
||||
}
|
||||
|
||||
return any
|
||||
}
|
||||
|
||||
override fun contains(key: Int): Boolean {
|
||||
return id2slot.containsKey(key)
|
||||
}
|
||||
|
||||
override fun containsAll(c: IntCollection): Boolean {
|
||||
return id2slot.keys.containsAll(c)
|
||||
}
|
||||
|
||||
override fun containsAll(elements: Collection<Int>): Boolean {
|
||||
return id2slot.keys.containsAll(elements)
|
||||
}
|
||||
|
||||
override fun isEmpty(): Boolean {
|
||||
return id2slot.isEmpty()
|
||||
}
|
||||
|
||||
override fun toArray(a: IntArray?): IntArray {
|
||||
return id2slot.keys.toArray(a)
|
||||
}
|
||||
|
||||
override fun toIntArray(): IntArray {
|
||||
return id2slot.keys.toIntArray()
|
||||
}
|
||||
|
||||
override val size: Int
|
||||
get() = id2slot.size
|
||||
}
|
||||
}
|
||||
|
||||
override val values: ReferenceCollection<T>
|
||||
get() = this@DynamicSynchableGroup
|
||||
}
|
||||
}
|
||||
|
||||
override val values: ReferenceCollection<T>
|
||||
get() = this
|
||||
|
||||
companion object {
|
||||
private const val END = 0
|
||||
private const val ADD_ENTRY = 1
|
||||
|
Loading…
Reference in New Issue
Block a user