Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SpeziFoundation #139

Merged
merged 13 commits into from
Nov 10, 2024
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package edu.stanford.spezi.core.utils.foundation

interface RepositoryAnchor
pauljohanneskraft marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package edu.stanford.spezi.core.utils.foundation

import edu.stanford.spezi.core.utils.foundation.knowledgesource.ComputedKnowledgeSource
import edu.stanford.spezi.core.utils.foundation.knowledgesource.ComputedKnowledgeSourceStoragePolicy
import edu.stanford.spezi.core.utils.foundation.knowledgesource.DefaultProvidingKnowledgeSource
import edu.stanford.spezi.core.utils.foundation.knowledgesource.KnowledgeSource
import edu.stanford.spezi.core.utils.foundation.knowledgesource.OptionalComputedKnowledgeSource
import kotlin.reflect.KClass

@Suppress("detekt:TooManyFunctions")
interface SharedRepository<Anchor : RepositoryAnchor> {
pauljohanneskraft marked this conversation as resolved.
Show resolved Hide resolved
operator fun <Value : Any> get(source: KnowledgeSource<Anchor, Value>): Value?
operator fun <Value : Any> set(source: KnowledgeSource<Anchor, Value>, value: Value?)

operator fun <Value : Any> get(
source: DefaultProvidingKnowledgeSource<Anchor, Value>,
): Value = getOrDefault(source)

fun <Value : Any> getOrDefault(
source: DefaultProvidingKnowledgeSource<Anchor, Value>,
): Value {
return get(
source as KnowledgeSource<Anchor, Value>,
) ?: source.defaultValue
}

operator fun <Value : Any> get(
source: ComputedKnowledgeSource<Anchor, Value>,
): Value = getOrComputed(source)

fun <Value : Any> getOrComputed(
source: ComputedKnowledgeSource<Anchor, Value>,
): Value {
return get(
source as KnowledgeSource<Anchor, Value>,
) ?: when (source.storagePolicy) {
is ComputedKnowledgeSourceStoragePolicy.AlwaysCompute -> {
source.compute(this)
}
is ComputedKnowledgeSourceStoragePolicy.Store -> {
val value = source.compute(this)
this[source] = value
value
}
}
}

operator fun <Value : Any> get(
source: OptionalComputedKnowledgeSource<Anchor, Value>,
): Value? = getOrOptionalComputed(source)

fun <Value : Any> getOrOptionalComputed(
source: OptionalComputedKnowledgeSource<Anchor, Value>,
): Value? {
return get(
source as KnowledgeSource<Anchor, Value>,
) ?: when (source.storagePolicy) {
ComputedKnowledgeSourceStoragePolicy.AlwaysCompute -> {
source.compute(this)
}
ComputedKnowledgeSourceStoragePolicy.Store -> {
val value = source.compute(this)
this[source] = value
value
}
}
}

fun <Value : Any> collect(allOf: KClass<Value>): List<Value>

fun <Value : Any> contains(source: KnowledgeSource<Anchor, Value>): Boolean {
return get(source) != null
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package edu.stanford.spezi.core.utils.foundation.builtin

import edu.stanford.spezi.core.utils.foundation.RepositoryAnchor
import edu.stanford.spezi.core.utils.foundation.SharedRepository
import edu.stanford.spezi.core.utils.foundation.knowledgesource.KnowledgeSource
import java.util.concurrent.ConcurrentHashMap
import kotlin.reflect.KClass

data class ValueRepository<Anchor : RepositoryAnchor>(
internal var storage: ConcurrentHashMap<KnowledgeSource<Anchor, *>, Any> = ConcurrentHashMap(),
) : SharedRepository<Anchor>, Sequence<Map.Entry<KnowledgeSource<Anchor, *>, Any>> {
@Suppress("UNCHECKED_CAST")
override operator fun <Value : Any> get(
source: KnowledgeSource<Anchor, Value>,
): Value? = storage[source] as? Value

override operator fun <Value : Any> set(
source: KnowledgeSource<Anchor, Value>,
value: Value?,
) {
value?.let {
storage[source] = it
} ?: storage.remove(source)
}

override fun <Value : Any> collect(allOf: KClass<Value>) =
storage.values.filterIsInstance(allOf.java)

override fun iterator() = storage.iterator()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package edu.stanford.spezi.core.utils.foundation.knowledgesource

import edu.stanford.spezi.core.utils.foundation.RepositoryAnchor
import edu.stanford.spezi.core.utils.foundation.SharedRepository

interface ComputedKnowledgeSource<Anchor : RepositoryAnchor, Value : Any> : SomeComputedKnowledgeSource<Anchor, Value> {
fun compute(repository: SharedRepository<Anchor>): Value
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package edu.stanford.spezi.core.utils.foundation.knowledgesource

import edu.stanford.spezi.core.utils.foundation.RepositoryAnchor

interface DefaultProvidingKnowledgeSource<Anchor : RepositoryAnchor, Value : Any> : KnowledgeSource<Anchor, Value> {
val defaultValue: Value
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package edu.stanford.spezi.core.utils.foundation.knowledgesource

import edu.stanford.spezi.core.utils.foundation.RepositoryAnchor

interface KnowledgeSource<Anchor : RepositoryAnchor, Value : Any>
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package edu.stanford.spezi.core.utils.foundation.knowledgesource

import edu.stanford.spezi.core.utils.foundation.RepositoryAnchor
import edu.stanford.spezi.core.utils.foundation.SharedRepository

interface OptionalComputedKnowledgeSource<
Anchor : RepositoryAnchor,
Value : Any,
> : SomeComputedKnowledgeSource<Anchor, Value> {

fun compute(repository: SharedRepository<Anchor>): Value?
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package edu.stanford.spezi.core.utils.foundation.knowledgesource

import edu.stanford.spezi.core.utils.foundation.RepositoryAnchor

sealed interface ComputedKnowledgeSourceStoragePolicy {
data object AlwaysCompute : ComputedKnowledgeSourceStoragePolicy
data object Store : ComputedKnowledgeSourceStoragePolicy
}

interface SomeComputedKnowledgeSource<Anchor : RepositoryAnchor, Value : Any> : KnowledgeSource<Anchor, Value> {
val storagePolicy: ComputedKnowledgeSourceStoragePolicy
}
Loading
Loading