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

commonMain.io.github.jan.supabase.collections.AtomicMutableList.kt Maven / Gradle / Ivy

There is a newer version: 3.0.2
Show newest version
package io.github.jan.supabase.collections

import io.github.jan.supabase.annotations.SupabaseInternal
import kotlinx.atomicfu.atomic
import kotlinx.atomicfu.update

/**
 * A multiplatform, thread-safe [MutableList], implemented using AtomicFU. Thanks to the author of [klogging](https://github.com/klogging/klogging)!
 */
@SupabaseInternal
class AtomicMutableList(
    vararg elements: E
) : MutableList {

    private val list = atomic(listOf(*elements))

    override val size: Int
        get() = list.value.size

    override fun clear(): Unit = list.update { buildList { emptyList() } }

    override fun addAll(elements: Collection): Boolean {
        var changed = false
        list.update { current ->
            buildList {
                addAll(current)
                changed = addAll(elements)
            }
        }
        return changed
    }

    override fun addAll(index: Int, elements: Collection): Boolean {
        var changed = false
        list.update { current ->
            buildList {
                addAll(current)
                changed = addAll(index, elements)
            }
        }
        return changed
    }

    override fun add(index: Int, element: E) = list.update { current ->
        buildList {
            addAll(current)
            add(index, element)
        }
    }

    override fun add(element: E): Boolean {
        list.update { current ->
            buildList {
                addAll(current)
                add(element)
            }
        }
        return true
    }

    override fun get(index: Int): E = list.value[index]

    override fun isEmpty(): Boolean = list.value.isEmpty()

    override fun iterator(): MutableIterator = list.value.toMutableList().iterator()

    override fun listIterator(): MutableListIterator = list.value.toMutableList().listIterator()

    override fun listIterator(index: Int): MutableListIterator = list.value.toMutableList().listIterator(index)

    override fun removeAt(index: Int): E {
        checkElementIndex(index, size)
        val removed: E = get(index)
        list.update { current ->
            buildList {
                addAll(current)
                removeAt(index)
            }
        }
        return removed
    }

    override fun subList(fromIndex: Int, toIndex: Int): MutableList =
        list.value.toMutableList().subList(fromIndex, toIndex)

    override fun set(index: Int, element: E): E {
        checkElementIndex(index, size)
        val replaced: E = get(index)
        list.update { current ->
            buildList {
                addAll(current)
                set(index, element)
            }
        }
        return replaced
    }

    override fun retainAll(elements: Collection): Boolean {
        var modified = false
        list.update { current ->
            buildList {
                addAll(current)
                modified = retainAll(elements)
            }
        }
        return modified
    }

    override fun removeAll(elements: Collection): Boolean {
        var modified = false
        list.update { current ->
            buildList {
                addAll(current)
                modified = removeAll(elements)
            }
        }
        return modified
    }

    override fun remove(element: E): Boolean {
        var modified = false
        list.update { current ->
            buildList {
                addAll(current)
                modified = remove(element)
            }
        }
        return modified
    }

    override fun lastIndexOf(element: E): Int = list.value.lastIndexOf(element)

    override fun indexOf(element: E): Int = list.value.indexOf(element)

    override fun containsAll(elements: Collection): Boolean = list.value.containsAll(elements)

    override fun contains(element: E): Boolean = list.value.contains(element)

    /**
     * Copied from Kotlin [AbstractList] internal code.
     */
    private fun checkElementIndex(index: Int, size: Int) {
        if (index < 0 || index >= size) {
            throw IndexOutOfBoundsException("index: $index, size: $size")
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy