11package nolambda.linkrouter
22
3- import nolambda.linkrouter.DeepLinkUri.Companion.toDeepLinkUri
43import nolambda.linkrouter.matcher.UriMatcher
54
65/* *
76 * router that use "key" to group [DeepLinkUri] or [DeepLinkEntry] for faster
87 * register and lookup
98 *
9+ * Flow:
10+ * 1. Register the route to [handlerMap] and [keyToUriMap]
11+ * 2. When resolving, it first search in [keyToEntryMap]
12+ * a. If no match, then search to [keyToUriMap], this will producing [DeepLinkEntry] and add it to [keyToEntryMap]
13+ * b. If match it will resulting the registered route
14+ * 3. Get the handler from [handlerMap] by using the registered route
15+ *
1016 * Please note, this router addition process is not thread-safe.
1117 */
1218class KeyUriRouter <URI >(
1319 private val logger : UriRouterLogger ? = null ,
14- private val keyExtractor : (DeepLinkUri ) -> String
20+ private val keyExtractor : (String ) -> String
1521) : UriRouter<URI>(logger) {
1622
17- private val keyToUriMap = mutableMapOf<String , MutableSet <Pair <DeepLinkUri , UriMatcher >>>()
18- private val keyToEntryMap = mutableMapOf<String , MutableSet <Pair <DeepLinkEntry , UriMatcher >>>()
23+ /* *
24+ * Key: From key extractor. Usually scheme + host + path
25+ * Value: Set of Pair of [DeepLinkEntry] and the matcher [UriMatcher]
26+ *
27+ * The result from here will be moved to [keyToEntryMap]
28+ * and the entry will be deleted after that
29+ */
30+ private val keyToUriMap = mutableMapOf<String , MutableSet <Pair <String , UriMatcher >>>()
31+
32+ /* *
33+ * Key: From key extractor. Usually scheme + host + path
34+ * Value: Set of Pair of [DeepLinkEntry] and the matcher [UriMatcher]
35+ *
36+ * If there's a value found in here, we don't need to search in [keyToUriMap]
37+ */
38+ private val keyToEntryMap =
39+ mutableMapOf<String , MutableSet <Triple <DeepLinkEntry , String , UriMatcher >>>()
1940
20- private val handlerMap = mutableMapOf<DeepLinkUri , UriRouterHandler <URI >>()
41+ /* *
42+ * Key: Registered route
43+ * Value: Registered lambda
44+ *
45+ * If we found registered route (key) from [keyToEntryMap] or [keyToUriMap]
46+ * we will find the registered lambda in here
47+ */
48+ private val handlerMap = mutableMapOf<String , UriRouterHandler <URI >>()
2149
2250 override fun clear () {
2351 keyToUriMap.clear()
2452 }
2553
2654 override fun resolveEntry (route : String ): Pair <DeepLinkEntry , EntryValue <URI >>? {
27- val deepLinkUri = route.toDeepLinkUri()
28- val key = keyExtractor(deepLinkUri)
55+ val key = keyExtractor(route)
2956
3057 logger?.run {
3158 invoke(" Key: $key " )
@@ -47,7 +74,7 @@ class KeyUriRouter<URI>(
4774
4875 var entry: DeepLinkEntry ? = null
4976 var matcher: UriMatcher ? = null
50- var pairOfUriAndMatcher: Pair <DeepLinkUri , UriMatcher >? = null
77+ var pairOfUriAndMatcher: Pair <String , UriMatcher >? = null
5178
5279 val uriList = keyToUriMap[key] ? : return null
5380 val actualKey = uriList.firstOrNull { pair ->
@@ -62,7 +89,7 @@ class KeyUriRouter<URI>(
6289
6390 // Add parsed entry to entry map
6491 val sets = keyToEntryMap.getOrPut(key) { mutableSetOf () }
65- sets.add(currentEntry to currentMatcher)
92+ sets.add(Triple ( currentEntry, pair.first, currentMatcher) )
6693
6794 currentMatcher.match(currentEntry, route)
6895 } ? : return null
@@ -85,25 +112,26 @@ class KeyUriRouter<URI>(
85112 route : String
86113 ): Pair <DeepLinkEntry , EntryValue <URI >>? {
87114 val set = keyToEntryMap[key] ? : return null
88- val actualKey = set.firstOrNull { (entry, matcher) ->
115+ val actualKey = set.firstOrNull { (entry, _, matcher) ->
89116 matcher.match(entry, route)
90117 } ? : return null
91118
92- return createResult(actualKey.first.uri , actualKey.first, actualKey.second )
119+ return createResult(actualKey.second , actualKey.first, actualKey.third )
93120 }
94121
95122 private fun createResult (
96- keyUri : DeepLinkUri ,
123+ registeredRoute : String ,
97124 entry : DeepLinkEntry ? ,
98125 matcher : UriMatcher ?
99126 ): Pair <DeepLinkEntry , EntryValue <URI >> {
100- val handler = handlerMap[keyUri] ? : error(" Handler not available for $keyUri " )
127+ val handler = handlerMap[registeredRoute]
128+ ? : error(" Handler not available for $registeredRoute " )
101129
102130 return Pair (
103- first = entry ? : error(" Entry not available fro $keyUri " ),
131+ first = entry ? : error(" Entry not available fro $registeredRoute " ),
104132 second = EntryValue (
105133 handler,
106- matcher ? : error(" Matcher not available fro $keyUri " )
134+ matcher ? : error(" Matcher not available fro $registeredRoute " )
107135 )
108136 )
109137 }
@@ -112,22 +140,19 @@ class KeyUriRouter<URI>(
112140 * This is not thread-safe
113141 */
114142 override fun addEntry (
115- vararg uri : String ,
143+ vararg uris : String ,
116144 matcher : UriMatcher ,
117145 handler : UriRouterHandler <URI >
118146 ) {
119- uri.forEach {
120- val deepLinkUri = it.toDeepLinkUri()
121- val key = keyExtractor(deepLinkUri)
122-
123- inputToEntryContainer(key, deepLinkUri, matcher)
124-
125- handlerMap[deepLinkUri] = handler
147+ uris.forEach { route ->
148+ val key = keyExtractor(route)
149+ inputToEntryContainer(key, route, matcher)
150+ handlerMap[route] = handler
126151 }
127152 }
128153
129- private fun inputToEntryContainer (key : String , uri : DeepLinkUri , matcher : UriMatcher ) {
154+ private fun inputToEntryContainer (key : String , registeredRoute : String , matcher : UriMatcher ) {
130155 val entriesHolder = keyToUriMap.getOrPut(key) { mutableSetOf () }
131- entriesHolder.add(uri to matcher)
156+ entriesHolder.add(registeredRoute to matcher)
132157 }
133158}
0 commit comments