From 46eb7caad5c3f5f4e84ee174372678636fcc7250 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fl=C3=A1vio=20Kreis?= Date: Tue, 5 Jun 2018 15:08:55 -0300 Subject: [PATCH] Change middlewares and reducers lists to maps (#52) * Changed middlewares and reducers lists to maps in Redukt * Udpated travis configuration to android 27 --- .travis.yml | 4 +- README.md | 6 +-- build.gradle | 6 +-- core/build.gradle | 11 ++--- .../com/github/raulccabreu/redukt/Redukt.kt | 28 +++++++----- .../utils/ConcurrentLinkedHashMapUtils.kt | 10 +++++ .../redukt/BaseAnnotatedMiddlewareTest.kt | 44 +++++++++---------- .../redukt/BaseAnnotatedReducerTest.kt | 20 ++++----- .../raulccabreu/redukt/DispatcherTest.kt | 6 +-- .../github/raulccabreu/redukt/ReduktTest.kt | 14 +++--- .../utils/ConcurrentLinkedHashMapUtilsTest.kt | 17 +++++++ gradle/wrapper/gradle-wrapper.properties | 4 +- ui/build.gradle | 14 +++--- 13 files changed, 108 insertions(+), 76 deletions(-) create mode 100644 core/src/main/java/com/github/raulccabreu/redukt/utils/ConcurrentLinkedHashMapUtils.kt create mode 100644 core/src/test/java/com/github/raulccabreu/redukt/utils/ConcurrentLinkedHashMapUtilsTest.kt diff --git a/.travis.yml b/.travis.yml index 7842dac..ecc0466 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,8 +7,8 @@ env: android: components: - tools - - build-tools-26.0.2 # TODO: build gradle without build-tools - - android-26 + - build-tools-27.0.3 # TODO: build gradle without build-tools + - android-27 - extra-android-m2repository jdk: diff --git a/README.md b/README.md index cf78aec..5b9896e 100644 --- a/README.md +++ b/README.md @@ -19,8 +19,8 @@ allprojects { Step 2. Add the dependency ```gradle dependencies { - compile 'com.github.raulccabreu.redukt:core:0.1.1' - compile 'com.github.raulccabreu.redukt:ui:0.1.1' + compile 'com.github.raulccabreu.redukt:core:0.1.3' + compile 'com.github.raulccabreu.redukt:ui:0.1.3' } ``` @@ -36,7 +36,7 @@ class CounterReducer : Reducer { } val redukt = Redukt(0) -redukt.reducers.add(CounterReducer()) +redukt.reducers["counterReducer"] = CounterReducer() redukt.listeners.add(object: StateListener { override fun hasChanged(newState: Int, oldState: Int) = newState != oldState override fun onChanged(state: Int) { println("count: $state") } diff --git a/build.gradle b/build.gradle index b6051c0..e3520e8 100644 --- a/build.gradle +++ b/build.gradle @@ -1,13 +1,13 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { - ext.kotlin_version = '1.2.10' + ext.kotlin_version = '1.2.41' repositories { google() jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:3.0.1' + classpath 'com.android.tools.build:gradle:3.1.2' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath 'com.github.dcendents:android-maven-gradle-plugin:2.0' @@ -23,7 +23,7 @@ allprojects { } } -project.ext.versionName = '0.1.1' +project.ext.versionName = '0.1.3' task clean(type: Delete) { delete rootProject.buildDir diff --git a/core/build.gradle b/core/build.gradle index 894f6e4..fdbccf1 100644 --- a/core/build.gradle +++ b/core/build.gradle @@ -12,12 +12,12 @@ tasks.withType(Test) { } android { - compileSdkVersion 26 + compileSdkVersion 27 defaultConfig { minSdkVersion 16 - targetSdkVersion 26 + targetSdkVersion 27 versionCode 1 - versionName "0.1.1" + versionName "0.1.3" } buildTypes { release { @@ -29,7 +29,8 @@ android { dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) - implementation "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version" + implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" + implementation "com.googlecode.concurrentlinkedhashmap:concurrentlinkedhashmap-lru:1.4.2" - testCompile 'junit:junit:4.12' + testImplementation 'junit:junit:4.12' } diff --git a/core/src/main/java/com/github/raulccabreu/redukt/Redukt.kt b/core/src/main/java/com/github/raulccabreu/redukt/Redukt.kt index c2c475b..3536d1c 100644 --- a/core/src/main/java/com/github/raulccabreu/redukt/Redukt.kt +++ b/core/src/main/java/com/github/raulccabreu/redukt/Redukt.kt @@ -5,24 +5,20 @@ import com.github.raulccabreu.redukt.middlewares.DebugMiddleware import com.github.raulccabreu.redukt.middlewares.Middleware import com.github.raulccabreu.redukt.reducers.Reducer import com.github.raulccabreu.redukt.states.StateListener +import com.github.raulccabreu.redukt.utils.createLinkedMap import java.util.concurrent.ConcurrentLinkedQueue import kotlin.system.measureTimeMillis -class Redukt(state: T, debug: Boolean = false) { +class Redukt(state: T, val debug: Boolean = false) { var state = state private set - val reducers = ConcurrentLinkedQueue>() - val middlewares = ConcurrentLinkedQueue>() + val reducers = createLinkedMap>() + val middlewares = createLinkedMap>() val listeners = ConcurrentLinkedQueue>() - val debug = debug private val dispatcher = Dispatcher { reduce(it) } init { - if (debug) { - val debugMiddleware = DebugMiddleware() - middlewares.add(debugMiddleware) - listeners.add(debugMiddleware) - } + addDebugMiddleware() start() } @@ -43,11 +39,11 @@ class Redukt(state: T, debug: Boolean = false) { val elapsed = measureTimeMillis { val oldState = state var tempState = state - middlewares.parallelFor { it.before(tempState, action) } - reducers.forEach { tempState = it.reduce(tempState, action) } + middlewares.ascendingMap().values.parallelFor { it.before(tempState, action) } + reducers.ascendingMap().values.forEach { tempState = it.reduce(tempState, action) } state = tempState listeners.parallelFor { notifyListeners(it, oldState) } - middlewares.parallelFor { it.after(tempState, action) } + middlewares.ascendingMap().values.parallelFor { it.after(tempState, action) } } log(" has spent [$elapsed ms] with [${action.name}]") } @@ -59,4 +55,12 @@ class Redukt(state: T, debug: Boolean = false) { private fun notifyListeners(it: StateListener, oldState: T) { if (it.hasChanged(state, oldState)) it.onChanged(state) } + + private fun addDebugMiddleware() { + if (!debug) return + + val debugMiddleware = DebugMiddleware() + middlewares["com.github.raulccabreu.redukt.debugMiddleware"] = debugMiddleware + listeners.add(debugMiddleware) + } } diff --git a/core/src/main/java/com/github/raulccabreu/redukt/utils/ConcurrentLinkedHashMapUtils.kt b/core/src/main/java/com/github/raulccabreu/redukt/utils/ConcurrentLinkedHashMapUtils.kt new file mode 100644 index 0000000..e736106 --- /dev/null +++ b/core/src/main/java/com/github/raulccabreu/redukt/utils/ConcurrentLinkedHashMapUtils.kt @@ -0,0 +1,10 @@ +package com.github.raulccabreu.redukt.utils + +import com.googlecode.concurrentlinkedhashmap.ConcurrentLinkedHashMap + +fun createLinkedMap(): ConcurrentLinkedHashMap { + return ConcurrentLinkedHashMap + .Builder() + .maximumWeightedCapacity(1000) + .build() +} \ No newline at end of file diff --git a/core/src/test/java/com/github/raulccabreu/redukt/BaseAnnotatedMiddlewareTest.kt b/core/src/test/java/com/github/raulccabreu/redukt/BaseAnnotatedMiddlewareTest.kt index f993dc6..4c5d975 100644 --- a/core/src/test/java/com/github/raulccabreu/redukt/BaseAnnotatedMiddlewareTest.kt +++ b/core/src/test/java/com/github/raulccabreu/redukt/BaseAnnotatedMiddlewareTest.kt @@ -38,7 +38,7 @@ class BaseAnnotatedMiddlewareTest { signal.countDown() } - redukt.middlewares.add(middleware) + redukt.middlewares["middleware"] = middleware redukt.dispatch(Action("valid", "new state"), false) @@ -58,7 +58,7 @@ class BaseAnnotatedMiddlewareTest { signal.countDown() }) - redukt.middlewares.add(middleware) + redukt.middlewares["middleware"] = middleware redukt.dispatch(Action("valid", "new state"), false) @@ -82,7 +82,7 @@ class BaseAnnotatedMiddlewareTest { signal.countDown() }) - redukt.middlewares.add(middleware) + redukt.middlewares["middleware"] = middleware redukt.dispatch(Action("valid", "new state"), false) @@ -112,8 +112,8 @@ class BaseAnnotatedMiddlewareTest { signal.countDown() }) - redukt.middlewares.add(middleware) - redukt.reducers.add(changerReducer) + redukt.middlewares["middleware"] = middleware + redukt.reducers["changerReducer"] = changerReducer redukt.dispatch(Action("valid", "new state"), false) @@ -128,7 +128,7 @@ class BaseAnnotatedMiddlewareTest { @Test fun invalidBeforeActionException() { try { - redukt.middlewares.add(InvalidBeforeAction()) + redukt.middlewares["invalidBeforeAction"] = InvalidBeforeAction() junit.framework.Assert.assertTrue(false) } catch (ex: Exception) { System.out.println("${ex.message}") @@ -139,7 +139,7 @@ class BaseAnnotatedMiddlewareTest { @Test fun invalidBeforeActionMethodsException() { try { - redukt.middlewares.add(InvalidBeforeActionMethods()) + redukt.middlewares["invalidBeforeActionMethods"] = InvalidBeforeActionMethods() junit.framework.Assert.assertTrue(false) } catch (ex: Exception) { System.out.println("${ex.message}") @@ -150,7 +150,7 @@ class BaseAnnotatedMiddlewareTest { @Test fun invalidAfterActionException() { try { - redukt.middlewares.add(InvalidAfterAction()) + redukt.middlewares["invalidAfterAction"] = InvalidAfterAction() junit.framework.Assert.assertTrue(false) } catch (ex: Exception) { System.out.println("${ex.message}") @@ -161,7 +161,7 @@ class BaseAnnotatedMiddlewareTest { @Test fun invalidAfterActionMethodsException() { try { - redukt.middlewares.add(InvalidAfterActionMethods()) + redukt.middlewares["invalidAfterActionMethods"] = InvalidAfterActionMethods() junit.framework.Assert.assertTrue(false) } catch (ex: Exception) { System.out.println("${ex.message}") @@ -179,7 +179,7 @@ class BaseAnnotatedMiddlewareTest { signal.countDown() } - redukt.middlewares.add(middleware) + redukt.middlewares["middleware"] = middleware redukt.dispatch(Action("valid", "new state"), false) @@ -199,7 +199,7 @@ class BaseAnnotatedMiddlewareTest { signal.countDown() }) - redukt.middlewares.add(middleware) + redukt.middlewares["middleware"] = middleware redukt.dispatch(Action("valid", "new state"), false) @@ -223,7 +223,7 @@ class BaseAnnotatedMiddlewareTest { signal.countDown() }) - redukt.middlewares.add(middleware) + redukt.middlewares["middleware"] = middleware redukt.dispatch(Action("valid", "new state"), false) @@ -249,7 +249,7 @@ class BaseAnnotatedMiddlewareTest { signal.countDown() }) - redukt.middlewares.add(middleware) + redukt.middlewares["middleware"] = middleware redukt.dispatch(Action("action_a", "new state"), false) @@ -288,7 +288,7 @@ class BaseAnnotatedMiddlewareTest { signal.countDown() }) - redukt.middlewares.add(middleware) + redukt.middlewares["middleware"] = middleware redukt.dispatch(Action("valid", "new state"), false) @@ -329,8 +329,8 @@ class BaseAnnotatedMiddlewareTest { signal.countDown() }) - redukt.middlewares.add(middleware) - redukt.reducers.add(reducer) + redukt.middlewares["middleware"] = middleware + redukt.reducers["reducer"] = reducer redukt.dispatch(Action("valid", "new state"), false) @@ -360,8 +360,8 @@ class BaseAnnotatedMiddlewareTest { signal.countDown() }) - redukt.middlewares.add(middleware) - redukt.reducers.add(reducer) + redukt.middlewares["middleware"] = middleware + redukt.reducers["reducer"] = reducer redukt.dispatch(Action("action_a", "new state"), false) @@ -389,7 +389,7 @@ class BaseAnnotatedMiddlewareTest { @Test fun invalidAfterActionsMethodsException() { try { - redukt.middlewares.add(InvalidAfterActionsMethods()) + redukt.middlewares["invalidAfterActionsMethods"] = InvalidAfterActionsMethods() junit.framework.Assert.assertTrue(false) } catch (ex: Exception) { System.out.println("${ex.message}") @@ -400,7 +400,7 @@ class BaseAnnotatedMiddlewareTest { @Test fun invalidBeforeActionsMethodsException() { try { - redukt.middlewares.add(InvalidBeforeActionsMethods()) + redukt.middlewares["invalidBeforeActionsMethods"] = InvalidBeforeActionsMethods() junit.framework.Assert.assertTrue(false) } catch (ex: Exception) { System.out.println("${ex.message}") @@ -434,8 +434,8 @@ class BaseAnnotatedMiddlewareTest { signal.countDown() }) - redukt.middlewares.add(middleware) - redukt.reducers.add(changerReducer) + redukt.middlewares["middleware"] = middleware + redukt.reducers["changerReducer"] = changerReducer redukt.dispatch(Action("valid", "new state"), false) diff --git a/core/src/test/java/com/github/raulccabreu/redukt/BaseAnnotatedReducerTest.kt b/core/src/test/java/com/github/raulccabreu/redukt/BaseAnnotatedReducerTest.kt index 193f653..54879ef 100644 --- a/core/src/test/java/com/github/raulccabreu/redukt/BaseAnnotatedReducerTest.kt +++ b/core/src/test/java/com/github/raulccabreu/redukt/BaseAnnotatedReducerTest.kt @@ -11,7 +11,7 @@ class BaseAnnotatedReducerTest { @Test fun whenUseValidBaseReducer() { val redukt = Redukt("initial") - redukt.reducers.add(ValidReducer()) + redukt.reducers["validReducer"] = ValidReducer() redukt.dispatch(Action("valid", "new state"), false) @@ -22,7 +22,7 @@ class BaseAnnotatedReducerTest { @Test fun whenUseValidBaseReducerExecuteTwice() { val redukt = Redukt("initial") - redukt.reducers.add(ValidReducer()) + redukt.reducers["validReducer"] = ValidReducer() redukt.dispatch(Action("valid", "new state"), false) redukt.dispatch(Action("valid", "new state2"), false) @@ -34,7 +34,7 @@ class BaseAnnotatedReducerTest { @Test fun whenUseInvalidBaseReducer() { val redukt = Redukt("initial") - redukt.reducers.add(ValidReducer()) + redukt.reducers["validReducer"] = ValidReducer() redukt.dispatch(Action("invalid", "new state"), false) @@ -45,8 +45,8 @@ class BaseAnnotatedReducerTest { @Test fun afterDispatchWithTwoReducers() { val redukt = Redukt("initial") - redukt.reducers.add(ValidReducer()) - redukt.reducers.add(UpperCaseReducer()) + redukt.reducers["validReducer"] = ValidReducer() + redukt.reducers["upperReducer"] = UpperCaseReducer() org.junit.Assert.assertEquals("initial", redukt.state) redukt.dispatch(Action("valid", "new state"), false) org.junit.Assert.assertEquals("NEW STATE", redukt.state) @@ -58,7 +58,7 @@ class BaseAnnotatedReducerTest { @Test fun afterDispatchTooManyActions() { val redukt = Redukt("initial") - redukt.reducers.add(ValidReducer()) + redukt.reducers["validReducer"] = ValidReducer() for(pos in 1 until 1001) { redukt.dispatch(Action("valid", "new state $pos"), false) } @@ -70,7 +70,7 @@ class BaseAnnotatedReducerTest { fun invalidArgumentException() { val redukt = Redukt("initial") try { - redukt.reducers.add(InvalidArgumentReducer()) + redukt.reducers["invalidArgumentReducer"] = InvalidArgumentReducer() Assert.assertTrue(false) } catch (ex: Exception) { System.out.println("${ex.message}") @@ -82,7 +82,7 @@ class BaseAnnotatedReducerTest { fun invalidParameterException() { val redukt = Redukt("initial") try { - redukt.reducers.add(InvalidParameterReducer()) + redukt.reducers["invalidParameterReducer"] = InvalidParameterReducer() Assert.assertTrue(false) } catch (ex: Exception) { System.out.println("${ex.message}") @@ -96,7 +96,7 @@ class BaseAnnotatedReducerTest { fun invalidReturnParameterException() { val redukt = Redukt("initial") try { - redukt.reducers.add(VoidReturnReducer()) + redukt.reducers["voidReturnReducer"] = VoidReturnReducer() Assert.assertTrue(false) } catch (ex: Exception) { System.out.println("${ex.message}") @@ -109,7 +109,7 @@ class BaseAnnotatedReducerTest { @Test fun invalidReturnParameter() { val redukt = Redukt("initial") - redukt.reducers.add(InvalidReturnReducer()) + redukt.reducers["invalidReturnReducer"] = InvalidReturnReducer() redukt.dispatch(Action("valid", "new state"), false) diff --git a/core/src/test/java/com/github/raulccabreu/redukt/DispatcherTest.kt b/core/src/test/java/com/github/raulccabreu/redukt/DispatcherTest.kt index 410622c..54f9425 100644 --- a/core/src/test/java/com/github/raulccabreu/redukt/DispatcherTest.kt +++ b/core/src/test/java/com/github/raulccabreu/redukt/DispatcherTest.kt @@ -20,7 +20,7 @@ class DispatcherTest { override fun hasChanged(newState: String, oldState: String) = true override fun onChanged(state: String) { signal.countDown() } } - redukt.reducers.add(changerReducer) + redukt.reducers["changerReducer"] = changerReducer redukt.listeners.add(listener) for(pos in 0 until actionsCount) { redukt.dispatch(Action("action", "new state $pos")) @@ -37,7 +37,7 @@ class DispatcherTest { val changerReducer = object: Reducer { override fun reduce(state: String, action: Action<*>) = action.payload.toString() } - redukt.reducers.add(changerReducer) + redukt.reducers["changerReducer"] = changerReducer for(pos in 0 until actionsCount) redukt.dispatch(Action("action", "")) redukt.stop() } @@ -57,7 +57,7 @@ class DispatcherTest { } redukt.listeners.add(listener) } - redukt.reducers.add(changerReducer) + redukt.reducers["changerReducer"] = changerReducer redukt.dispatch(Action("action", "new state")) signal.await() assertEquals("new state", redukt.state) diff --git a/core/src/test/java/com/github/raulccabreu/redukt/ReduktTest.kt b/core/src/test/java/com/github/raulccabreu/redukt/ReduktTest.kt index 59f4508..38c69cc 100644 --- a/core/src/test/java/com/github/raulccabreu/redukt/ReduktTest.kt +++ b/core/src/test/java/com/github/raulccabreu/redukt/ReduktTest.kt @@ -20,9 +20,9 @@ class ReduktTest { val reducer = object: Reducer { override fun reduce(state: String, action: Action<*>) = state } - redukt.reducers.add(reducer) + redukt.reducers["reducer"] = reducer assertEquals(1, redukt.reducers.size) - assertEquals(reducer, redukt.reducers.first()) + assertEquals(reducer, redukt.reducers.values.first()) redukt.stop() } @@ -32,7 +32,7 @@ class ReduktTest { val reducer = object: Reducer { override fun reduce(state: String, action: Action<*>) = action.payload.toString() } - redukt.reducers.add(reducer) + redukt.reducers["reducer"] = reducer assertEquals("initial", redukt.state) redukt.dispatch(Action("action", "new state"), false) assertEquals("new state", redukt.state) @@ -47,11 +47,11 @@ class ReduktTest { val changerReducer = object: Reducer { override fun reduce(state: String, action: Action<*>) = action.payload.toString() } - val upcaseReducer = object: Reducer { + val upperCaseReducer = object: Reducer { override fun reduce(state: String, action: Action<*>) = state.toUpperCase() } - redukt.reducers.add(changerReducer) - redukt.reducers.add(upcaseReducer) + redukt.reducers["changerReducer"] = changerReducer + redukt.reducers["upperCaseReducer"] = upperCaseReducer assertEquals("initial", redukt.state) redukt.dispatch(Action("action", "new state"), false) assertEquals("NEW STATE", redukt.state) @@ -66,7 +66,7 @@ class ReduktTest { val changerReducer = object: Reducer { override fun reduce(state: String, action: Action<*>) = action.payload.toString() } - redukt.reducers.add(changerReducer) + redukt.reducers["changerReducer"] = changerReducer for(pos in 1 until 101) { redukt.dispatch(Action("action", "new state $pos"), false) } diff --git a/core/src/test/java/com/github/raulccabreu/redukt/utils/ConcurrentLinkedHashMapUtilsTest.kt b/core/src/test/java/com/github/raulccabreu/redukt/utils/ConcurrentLinkedHashMapUtilsTest.kt new file mode 100644 index 0000000..05aee40 --- /dev/null +++ b/core/src/test/java/com/github/raulccabreu/redukt/utils/ConcurrentLinkedHashMapUtilsTest.kt @@ -0,0 +1,17 @@ +package com.github.raulccabreu.redukt.utils + +import com.googlecode.concurrentlinkedhashmap.ConcurrentLinkedHashMap +import org.junit.Assert.assertEquals +import org.junit.Assert.assertTrue +import org.junit.Test + +class ConcurrentLinkedHashMapUtilsTest { + + @Test + fun createLinkedMapWorks() { + val map = createLinkedMap() + + assertEquals(1000, map.capacity()) + assertTrue(map is ConcurrentLinkedHashMap) + } +} \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index ebb5070..81bdf3e 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Wed Nov 15 22:06:54 BRT 2017 +#Tue May 29 14:49:36 BRT 2018 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-all.zip diff --git a/ui/build.gradle b/ui/build.gradle index ae3979a..95979eb 100644 --- a/ui/build.gradle +++ b/ui/build.gradle @@ -12,13 +12,13 @@ tasks.withType(Test) { } android { - compileSdkVersion 26 + compileSdkVersion 27 defaultConfig { minSdkVersion 16 - targetSdkVersion 26 + targetSdkVersion 27 versionCode 1 - versionName "0.1.1" + versionName "0.1.3" } buildTypes { @@ -35,11 +35,11 @@ dependencies { implementation project(path: ':core') - implementation 'com.android.support:appcompat-v7:26.1.0' + implementation 'com.android.support:appcompat-v7:27.1.1' testImplementation 'junit:junit:4.12' - androidTestImplementation 'com.android.support.test:runner:1.0.1' - androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1' - compile "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version" + androidTestImplementation 'com.android.support.test:runner:1.0.2' + androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' + implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" } repositories { mavenCentral()