From 00baa0c063c6b57605f33b662eca57ab69620cf5 Mon Sep 17 00:00:00 2001 From: tursom Date: Tue, 5 Apr 2022 20:24:30 +0800 Subject: [PATCH] add Context --- .../cn/tursom/core/context/ArrayContextEnv.kt | 36 +++++++++++++++++++ .../kotlin/cn/tursom/core/context/Context.kt | 15 ++++++++ .../cn/tursom/core/context/ContextEnv.kt | 13 +++++++ .../cn/tursom/core/context/ContextKey.kt | 6 ++++ .../tursom/core/context/HashMapContextEnv.kt | 28 +++++++++++++++ 5 files changed, 98 insertions(+) create mode 100644 ts-core/src/main/kotlin/cn/tursom/core/context/ArrayContextEnv.kt create mode 100644 ts-core/src/main/kotlin/cn/tursom/core/context/Context.kt create mode 100644 ts-core/src/main/kotlin/cn/tursom/core/context/ContextEnv.kt create mode 100644 ts-core/src/main/kotlin/cn/tursom/core/context/ContextKey.kt create mode 100644 ts-core/src/main/kotlin/cn/tursom/core/context/HashMapContextEnv.kt diff --git a/ts-core/src/main/kotlin/cn/tursom/core/context/ArrayContextEnv.kt b/ts-core/src/main/kotlin/cn/tursom/core/context/ArrayContextEnv.kt new file mode 100644 index 0000000..cca586c --- /dev/null +++ b/ts-core/src/main/kotlin/cn/tursom/core/context/ArrayContextEnv.kt @@ -0,0 +1,36 @@ +package cn.tursom.core.context + +import cn.tursom.core.uncheckedCast +import java.util.concurrent.atomic.AtomicInteger + +class ArrayContextEnv : ContextEnv { + val envId = ContextEnv.newEnvId() + private val idGenerator = AtomicInteger() + + override fun newContext(): Context = ArrayContext(envId, idGenerator) + override fun newKey() = ContextKey(envId, idGenerator.getAndIncrement()) + + private class ArrayContext( + override val envId: Int, + private val idGenerator: AtomicInteger, + ) : Context { + private var array = arrayOfNulls(idGenerator.get()) + + override operator fun get(key: ContextKey): T? { + checkEnv(key) + return if (array.size < key.id) { + null + } else { + array[key.id]?.uncheckedCast() + } + } + + override operator fun set(key: ContextKey, value: T) { + checkEnv(key) + if (array.size < key.id) { + array = array.copyOf(idGenerator.get()) + } + array[key.id] = value + } + } +} diff --git a/ts-core/src/main/kotlin/cn/tursom/core/context/Context.kt b/ts-core/src/main/kotlin/cn/tursom/core/context/Context.kt new file mode 100644 index 0000000..ea0820d --- /dev/null +++ b/ts-core/src/main/kotlin/cn/tursom/core/context/Context.kt @@ -0,0 +1,15 @@ +package cn.tursom.core.context + + +interface Context { + val envId: Int + operator fun get(key: ContextKey): T? + operator fun set(key: ContextKey, value: T) + + fun checkEnv(key: ContextKey<*>) { + if (envId != key.envId) { + throw UnsupportedOperationException() + } + } +} + diff --git a/ts-core/src/main/kotlin/cn/tursom/core/context/ContextEnv.kt b/ts-core/src/main/kotlin/cn/tursom/core/context/ContextEnv.kt new file mode 100644 index 0000000..71c97f6 --- /dev/null +++ b/ts-core/src/main/kotlin/cn/tursom/core/context/ContextEnv.kt @@ -0,0 +1,13 @@ +package cn.tursom.core.context + +import java.util.concurrent.atomic.AtomicInteger + +interface ContextEnv { + companion object { + private val contextEnvIdGenerator = AtomicInteger() + fun newEnvId() = contextEnvIdGenerator.incrementAndGet() + } + + fun newContext(): Context + fun newKey(): ContextKey +} diff --git a/ts-core/src/main/kotlin/cn/tursom/core/context/ContextKey.kt b/ts-core/src/main/kotlin/cn/tursom/core/context/ContextKey.kt new file mode 100644 index 0000000..25833e5 --- /dev/null +++ b/ts-core/src/main/kotlin/cn/tursom/core/context/ContextKey.kt @@ -0,0 +1,6 @@ +package cn.tursom.core.context + +data class ContextKey( + val envId: Int, + val id: Int, +) diff --git a/ts-core/src/main/kotlin/cn/tursom/core/context/HashMapContextEnv.kt b/ts-core/src/main/kotlin/cn/tursom/core/context/HashMapContextEnv.kt new file mode 100644 index 0000000..23b2b02 --- /dev/null +++ b/ts-core/src/main/kotlin/cn/tursom/core/context/HashMapContextEnv.kt @@ -0,0 +1,28 @@ +package cn.tursom.core.context + +import cn.tursom.core.uncheckedCast +import java.util.concurrent.atomic.AtomicInteger + +class HashMapContextEnv : ContextEnv { + val envId = ContextEnv.newEnvId() + private val idGenerator = AtomicInteger() + + override fun newContext(): Context = HashMapContext(envId) + override fun newKey() = ContextKey(envId, idGenerator.getAndIncrement()) + + private class HashMapContext( + override val envId: Int, + ) : Context { + private var map = HashMap() + + override operator fun get(key: ContextKey): T? { + checkEnv(key) + return map[key.id]?.uncheckedCast() + } + + override operator fun set(key: ContextKey, value: T) { + checkEnv(key) + map[key.id] = value + } + } +}