Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,12 @@ jobs:
- name: Grant execute permission for Gradlew
run: chmod +x gradlew

- name: Check Kotlin formatting
run: ./gradlew spotlessCheck :tooling:plugins:spotlessCheck

- name: Run Kotlin static analysis
run: ./gradlew detekt :tooling:plugins:detekt

- name: Build and Test with Coverage
run: ./gradlew clean build koverXmlReport --stacktrace

Expand Down
28 changes: 20 additions & 8 deletions build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
plugins {
alias(libs.plugins.ktlint)
id("com.diffplug.spotless") version "6.4.1"
alias(libs.plugins.spotless)
alias(libs.plugins.detekt)
}

buildscript {
Expand All @@ -15,7 +15,6 @@ buildscript {
classpath(libs.kotlin.gradle.plugin)
classpath(libs.kotlin.serialization.plugin)
classpath(libs.dokka.gradle.plugin)
classpath(libs.ktlint.gradle.plugin)
classpath(libs.jacoco.gradle.plugin)
classpath(libs.maven.publish.plugin)
classpath(libs.atomic.fu.gradle.plugin)
Expand All @@ -32,18 +31,31 @@ allprojects {
}

subprojects {
apply(plugin = "org.jlleitschuh.gradle.ktlint")
apply(plugin = "com.diffplug.spotless")

ktlint {
disabledRules.add("import-ordering")
}
apply(plugin = "io.gitlab.arturbosch.detekt")

spotless {
kotlin {
ktfmt(libs.versions.ktfmt.get()).googleStyle()
target("src/**/*.kt")
trimTrailingWhitespace()
endWithNewline()
}

kotlinGradle {
ktfmt(libs.versions.ktfmt.get()).googleStyle()
target("*.kts")
trimTrailingWhitespace()
endWithNewline()
}
}

detekt {
buildUponDefaultConfig = true
baseline = file("${projectDir}/config/detekt/baseline.xml")
config.setFrom("$rootDir/config/detekt/rules.yml")
source.setFrom("src")
}
}

tasks {
Expand Down
37 changes: 16 additions & 21 deletions cache/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,26 +1,21 @@
plugins {
id("org.mobilenativefoundation.store.multiplatform")
}
plugins { id("org.mobilenativefoundation.store.multiplatform") }

kotlin {

sourceSets {
val commonMain by getting {
dependencies {
api(libs.kotlinx.atomic.fu)
api(projects.core)
implementation(libs.kotlinx.coroutines.core)
}
}
val commonTest by getting {
dependencies {
implementation(libs.junit)
implementation(libs.kotlinx.coroutines.test)
}
}
sourceSets {
val commonMain by getting {
dependencies {
api(libs.kotlinx.atomic.fu)
api(projects.core)
implementation(libs.kotlinx.coroutines.core)
}
}
val commonTest by getting {
dependencies {
implementation(libs.junit)
implementation(libs.kotlinx.coroutines.test)
}
}
}
}

android {
namespace = "org.mobilenativefoundation.store.cache"
}
android { namespace = "org.mobilenativefoundation.store.cache" }
50 changes: 50 additions & 0 deletions cache/config/detekt/baseline.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<?xml version='1.0' encoding='UTF-8'?>
<SmellBaseline>
<ManuallySuppressedIssues/>
<CurrentIssues>
<ID>EmptyFunctionBlock:LocalCache.kt$LocalCache.Companion.&lt;no name provided>${}</ID>
<ID>EmptyFunctionBlock:LocalCache.kt$LocalCache.StrongValueReference${}</ID>
<ID>LongMethod:LocalCache.kt$LocalCache.Segment$fun put( key: K, hash: Int, value: V, onlyIfAbsent: Boolean, ): V?</ID>
<ID>LongParameterList:LocalCache.kt$LocalCache.Segment$( first: ReferenceEntry&lt;K, V>, entry: ReferenceEntry&lt;K, V>, key: K, hash: Int, valueReference: ValueReference&lt;K, V>, cause: RemovalCause?, )</ID>
<ID>MagicNumber:CacheBuilder.kt$CacheBuilder$16</ID>
<ID>MagicNumber:CacheBuilder.kt$CacheBuilder$4</ID>
<ID>MagicNumber:LocalCache.kt$LocalCache$20</ID>
<ID>MagicNumber:LocalCache.kt$LocalCache$32</ID>
<ID>MagicNumber:LocalCache.kt$LocalCache.Companion$10</ID>
<ID>MagicNumber:LocalCache.kt$LocalCache.Companion$14</ID>
<ID>MagicNumber:LocalCache.kt$LocalCache.Companion$15</ID>
<ID>MagicNumber:LocalCache.kt$LocalCache.Companion$16</ID>
<ID>MagicNumber:LocalCache.kt$LocalCache.Companion$3</ID>
<ID>MagicNumber:LocalCache.kt$LocalCache.Companion$6</ID>
<ID>MagicNumber:LocalCache.kt$LocalCache.Segment$3</ID>
<ID>MagicNumber:LocalCache.kt$LocalCache.Segment$4</ID>
<ID>MaxLineLength:Cache.kt$Cache$*</ID>
<ID>MaxLineLength:LocalCache.kt$LocalCache.WriteQueue$*</ID>
<ID>MaxLineLength:MonotonicTicker.kt$internal</ID>
<ID>MaxLineLength:RemovalCause.kt$RemovalCause$*</ID>
<ID>MaxLineLength:StoreMultiCache.kt$StoreMultiCache$class</ID>
<ID>MaxLineLength:StoreMultiCache.kt$StoreMultiCache$collectionsCache: Cache&lt;StoreKey.Collection&lt;Id>, Collection> = CacheBuilder&lt;StoreKey.Collection&lt;Id>, Collection>().build()</ID>
<ID>MaxLineLength:StoreMultiCache.kt$StoreMultiCache.Companion$fun invalidKeyErrorMessage(key: Any)</ID>
<ID>MaxLineLength:Weigher.kt$* @return Weight of a cache entry. Must be non-negative. There is no unit for entry weights. Rather, they are simply relative to each other.</ID>
<ID>NestedBlockDepth:LocalCache.kt$LocalCache.Segment$fun activeEntries(): Map&lt;K, V></ID>
<ID>NestedBlockDepth:LocalCache.kt$LocalCache.Segment$fun clear()</ID>
<ID>NestedBlockDepth:LocalCache.kt$LocalCache.Segment$fun put( key: K, hash: Int, value: V, onlyIfAbsent: Boolean, ): V?</ID>
<ID>NestedBlockDepth:LocalCache.kt$LocalCache.Segment$fun remove( key: K, hash: Int, ): V?</ID>
<ID>NestedBlockDepth:LocalCache.kt$LocalCache.Segment$private fun expand()</ID>
<ID>ReturnCount:LocalCache.kt$LocalCache.Segment$fun get( key: K, hash: Int, ): V?</ID>
<ID>ReturnCount:LocalCache.kt$LocalCache.Segment$fun remove( key: K, hash: Int, ): V?</ID>
<ID>ReturnCount:LocalCache.kt$LocalCache.Segment$private fun getLiveEntry( key: K, hash: Int, now: Long, ): ReferenceEntry&lt;K, V>?</ID>
<ID>TooManyFunctions:LocalCache.kt$LocalCache$Segment&lt;K : Any, V : Any></ID>
<ID>TooManyFunctions:LocalCache.kt$LocalCache&lt;K : Any, V : Any></ID>
<ID>TooManyFunctions:StoreMultiCache.kt$StoreMultiCache&lt;Id : Any, Key : StoreKey&lt;Id>, Single : StoreData.Single&lt;Id>, Collection : StoreData.Collection&lt;Id, Single>, Output : StoreData&lt;Id>> : Cache</ID>
<ID>UnusedParameter:LocalCache.kt$LocalCache.Segment$cause: RemovalCause?</ID>
<ID>UnusedParameter:LocalCache.kt$LocalCache.Segment$hash: Int</ID>
<ID>UnusedParameter:LocalCache.kt$LocalCache.Segment$key: K?</ID>
<ID>UnusedPrivateMember:LocalCache.kt$LocalCache$private fun newValueReference( entry: ReferenceEntry&lt;K, V>, value: V, weight: Int, ): ValueReference&lt;K, V></ID>
<ID>UseCheckOrError:CacheBuilder.kt$CacheBuilder$throw IllegalStateException("Maximum size cannot be combined with weigher.")</ID>
<ID>UseCheckOrError:LocalCache.kt$LocalCache.Segment$throw IllegalStateException("Weights must be non-negative")</ID>
<ID>UseRequire:CacheBuilder.kt$CacheBuilder$throw IllegalArgumentException("Duration must be non-negative.")</ID>
<ID>UseRequire:CacheBuilder.kt$CacheBuilder$throw IllegalArgumentException("Maximum size must be non-negative.")</ID>
<ID>UseRequire:CacheBuilder.kt$CacheBuilder$throw IllegalArgumentException("Maximum weight must be non-negative.")</ID>
</CurrentIssues>
</SmellBaseline>
24 changes: 0 additions & 24 deletions cache/config/ktlint/baseline.xml

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,69 +1,55 @@
package org.mobilenativefoundation.store.cache5

interface Cache<Key : Any, Value : Any> {
/**
* @return [Value] associated with [key] or `null` if there is no cached value for [key].
*/
fun getIfPresent(key: Key): Value?

/**
* @return [Value] associated with [key], obtaining the value from [valueProducer] if necessary.
* No observable state associated with this cache is modified until loading completes.
* @param [valueProducer] Must not return `null`. It may either return a non-null value or throw an exception.
* @throws ExecutionExeption If a checked exception was thrown while loading the value.
* @throws UncheckedExecutionException If an unchecked exception was thrown while loading the value.
* @throws ExecutionError If an error was thrown while loading the value.
*/
fun getOrPut(
key: Key,
valueProducer: () -> Value,
): Value

/**
* @return Map of the [Value] associated with each [Key] in [keys]. Returned map only contains entries already present in the cache.
* The default implementation provided here throws a [NotImplementedError] to maintain backward compatibility for existing implementations.
*/
fun getAllPresent(keys: List<*>): Map<Key, Value>

/**
* @return Map of the [Value] associated with each [Key] in the cache.
*/
fun getAllPresent(): Map<Key, Value> = throw NotImplementedError()

/**
* Associates [value] with [key].
* If the cache previously contained a value associated with [key], the old value is replaced by [value].
* Prefer [getOrPut] when using the conventional "If cached, then return. Otherwise create, cache, and then return" pattern.
*/
fun put(
key: Key,
value: Value,
)

/**
* Copies all of the mappings from the specified map to the cache. The effect of this call is
* equivalent to that of calling [put] on this map once for each mapping from [Key] to [Value] in the specified map.
* The behavior of this operation is undefined if the specified map is modified while the operation is in progress.
*/
fun putAll(map: Map<Key, Value>)

/**
* Discards any cached value associated with [key].
*/
fun invalidate(key: Key)

/**
* Discards any cached value associated for [keys].
*/
fun invalidateAll(keys: List<Key>)

/**
* Discards all entries in the cache.
*/
fun invalidateAll()

/**
* @return Approximate number of entries in the cache.
*/
fun size(): Long
/** @return [Value] associated with [key] or `null` if there is no cached value for [key]. */
fun getIfPresent(key: Key): Value?

/**
* @param [valueProducer] Must not return `null`. It may either return a non-null value or throw
* an exception.
* @return [Value] associated with [key], obtaining the value from [valueProducer] if necessary.
* No observable state associated with this cache is modified until loading completes.
* @throws ExecutionExeption If a checked exception was thrown while loading the value.
* @throws UncheckedExecutionException If an unchecked exception was thrown while loading the
* value.
* @throws ExecutionError If an error was thrown while loading the value.
*/
fun getOrPut(key: Key, valueProducer: () -> Value): Value

/**
* @return Map of the [Value] associated with each [Key] in [keys]. Returned map only contains
* entries already present in the cache. The default implementation provided here throws a
* [NotImplementedError] to maintain backward compatibility for existing implementations.
*/
fun getAllPresent(keys: List<*>): Map<Key, Value>

/** @return Map of the [Value] associated with each [Key] in the cache. */
fun getAllPresent(): Map<Key, Value> = throw NotImplementedError()

/**
* Associates [value] with [key]. If the cache previously contained a value associated with [key],
* the old value is replaced by [value]. Prefer [getOrPut] when using the conventional "If cached,
* then return. Otherwise create, cache, and then return" pattern.
*/
fun put(key: Key, value: Value)

/**
* Copies all of the mappings from the specified map to the cache. The effect of this call is
* equivalent to that of calling [put] on this map once for each mapping from [Key] to [Value] in
* the specified map. The behavior of this operation is undefined if the specified map is modified
* while the operation is in progress.
*/
fun putAll(map: Map<Key, Value>)

/** Discards any cached value associated with [key]. */
fun invalidate(key: Key)

/** Discards any cached value associated for [keys]. */
fun invalidateAll(keys: List<Key>)

/** Discards all entries in the cache. */
fun invalidateAll()

/** @return Approximate number of entries in the cache. */
fun size(): Long
}
Loading
Loading