Skip to content

Commit

Permalink
Greatly improve performance with remote HTTP tiles.
Browse files Browse the repository at this point in the history
Leverage back-pressure, simplified the core.

Update Readme
  • Loading branch information
p-lr committed Nov 12, 2019
1 parent f69f6d6 commit c423e02
Show file tree
Hide file tree
Showing 8 changed files with 60 additions and 58 deletions.
4 changes: 2 additions & 2 deletions Readme.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
[ ![Download](https://api.bintray.com/packages/peterlaurence/maven/mapview/images/download.svg?version=1.0.3) ](https://bintray.com/peterlaurence/maven/mapview/1.0.3/link)
[ ![Download](https://api.bintray.com/packages/peterlaurence/maven/mapview/images/download.svg?version=1.0.4) ](https://bintray.com/peterlaurence/maven/mapview/1.0.4/link)

# MapView

Expand Down Expand Up @@ -29,7 +29,7 @@ This project holds the source code of this library, but also a demo app (which i

Add this to your module's build.gradle
```groovy
implementation 'com.peterlaurence:mapview:1.0.3'
implementation 'com.peterlaurence:mapview:1.0.4'
```

## Origin and motivation
Expand Down
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ buildscript {

}
dependencies {
classpath 'com.android.tools.build:gradle:3.5.1'
classpath 'com.android.tools.build:gradle:3.5.2'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath "org.jetbrains.kotlin:kotlin-serialization:$kotlin_version"
// NOTE: Do not place your application dependencies here; they belong
Expand Down
2 changes: 1 addition & 1 deletion doc/technical/mapview/MapView.drawio
Original file line number Diff line number Diff line change
@@ -1 +1 @@
<mxfile modified="2019-06-23T07:06:38.443Z" host="www.draw.io" agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.90 Safari/537.36" etag="iE7Z7vuxXtPxiJQQoQrZ" version="10.8.0" type="device"><diagram name="Page-1" id="b33cb84f-bf7a-9ccf-f142-242d16432e5d">7V1tc5s6Fv41/lgPekV8zEvT3Z3b3c60e7v9SIxsMyXGF5PE6a9fCSMMkmwLAthpbjrTBGGEOc9519Fhgm4etp+ycL38nEY8mUAv2k7Q7QRCEBAifsmRl3LEY/5uZJHFUTm2H/ga/+Lqg+XoYxzxTeODeZomebxuDs7S1YrP8sZYmGXpc/Nj8zRp3nUdLrgx8HUWJmp0Svbj3+MoX5bjgAb7E//g8WJZ3pxBujtxH85+LrL0cVXecQLRvPjZnX4I1Vzlo26WYZQ+14bQxwm6ydI03/31sL3hiSSvIpy6Ln9R33aCrpf5QyIOgPizOH134GLgcrF4uIyv8vrtDs33+H39/Auyu/CfL//9a/XjG7xm8w9wN8tTmDyqm0CaiPmu56mYtn57+tdjqk582BR8cCU+AMh6uz8p/lrI35/D9Z8xf1aTiW+1m2931niyAgQelU/2vIxz/nUdzuTZZ8G3zQefx0lykyZpVlyLopCz+UyMb/Is/clrZ+iM8fu5lVQlcZ94lvNtbagk3SeePvA8exEfKc/6rARTyYk6fq6xnAJ8WeM2Wo6FJZ8vqqn3WIk/SrhaQIcGgu5bnPCbcPUUbuoI3md78AbAtAeEmIYQ8oiJEB4TIWxBSCMSX0VXUgmKo1kSbjbxrEkXQY7s5X/iwBNqrjz8UT93K5/eq45e1NE2zmuXiaMftTP7i+SBukaXK8JZhG1yxeA9orQ6o5QuLEbCLFdPtEpXXI3dxZJ25TeNyqOjyG/Sx2zGj5CXldYmzBY8Py0oPGoYEpOPanxCLGyixjKehHn81DRKNt4p7/AljQtxVEwMNEVSaRI1x+7By8vqCl2fieozIW2mHWmMmQpmrh68O3+TVvxdcoOduf3BuXv2mD1V2qi9CTFZvTvjIkfGhZfNuNXEbRnX95szUX2iA3wrOCl8qX1sLT+wOfyNA9i8j9L0ezHYzdirULCBzLI0xqX7fsD+mob6oEX2xrHIQZP+xDu3zxQY4EhvZ2NQSjxg3iRHmMSLlbTSghxcKIdrSYZYhCFX5YmHOIrk5Va6Nn0hCVsZSAHcyfD2AE6gWQ+MTHBs3hIcChtoukvXcf4Qrr+IcNKBu03MMi6EKrwvPiA5vtQX4tPkekJuJaqPebopkaiBnPB5boE4TyWWGwFtvFp8kwe3H7AFzz7Q0ZStD010glHRoa2MvdWZNW2oTrmu7m57e97FhWg4t/snrPu3r/NoAXb0DNhFeQaBbs9BV48WUW8KKBCsjcS3YyqCUxEdCqYMMd8LqO9jECDk5Db0Zdmhf1oEWplYnfujcLOsjEQPSgQAoul4iwEmVjXC4FB6xPSPioRDmiR8lgsxfV1qqH9NDBBuEhG5Zn4QGYiGwOZjamQ7Qagmn1aJTc/Q0pZoiRY/TWpDXDOf2Y4GmvYt478+jCMDTX1DfBMRCyC6WuoPEJdMT5LE680hB3FYx5siC4FsLKunIrpQCIYk9EAUQY4Bmt8L6sB3zq6K+hW7wjOzq0Pi5rcGhFwaIA6exW8NiLJoChD/3ICYiYL3BYh/YYAoY/VuAdFtyNkBAe8cEN2GnB2Qv72sJiCBJUwbFRDbAv17AkSXkHMDgh2iNFkOtHZ/+KqsqcwyT+qFQdZsgsfwtJnVImqqOl1QVdY0SnYXO2jzdqmtHmp0joPozIfUpK4t9B2MtsghW+OcHDi+kGRQ1/94RT96g1C3Tk8wJqs6qNU3SM5txZpTS9nSqAS2ZQcaK9iziiL7RWoUBJ4n08v6unUts6sv4f3k2Ypbl/bcKsycYQ43613p6TzeSrR13JvKas5mfDZz4Yd7RjCx80P7PDPU6tdwYDICGyhnZy/vcTAKZ7CXmFo87ZHtpUoYXb69JK0Z8dz2krwhBd+CuudS56TPtYnLIefl2EtiX9H8KkyO1HfLcFUYOY3kw1UYeRoyNgu32+WArhdZGMXifrZzfdg04Hl6tINNuIJgTLhsqd2WBXpgvd25KZbS+Trmbm7MZbBCL3ADHW6MzaDf5sQMBjftO7I9rOS6CJmOTu8lIESrzcEW+Ttg3weDxLRIVydKP7rggigKUGTHhTEL7fsgt+7EkwA58T+CQxHbjOa+p5mIvOSjFoWVb5/oRCt3wB47M9EdiiUHj5ywqkqpqq8DU/K9UXVx7wV0Q0VNFYDOTCiiVAp95FMMCSNEebJ1LwdMhffjE8gI8IWlhGNS/g3lIFvQvi7fU0SJBwLhnGGPMpV5G4e6DtUCb5C6VXHGlCIcMC9gTJgzYOYHzkl75d5clqq1eL3jqlr/zSzoVAD+JqpW1QG8BWXQgvaXIu5vKDnYnrMvXNU6ZBIbu2zb7QeyYbDfDzSp7QaqbQ46uUE4KKKOan/PFPlw0mITfLUWdHjtR17+hWexILLM1dweXQ+6kB07AJFg6gl+g7T4GzbNl2AzHzJACEKCGVWCs/VuHgzY1AOYUAQ86gekWVNIgPgKYpgCIFgaM223RE97gAHSN6GWtZ2DbgL2zai7yAnnYf64mbz3rLDuLmFmxuuj5oR9M17/G646XHoSn1p8rlEBc8gk9GyK2m/SroxXtXvVzXgdxOzktlCV270UK1MYAA8QCJjQ88KWNLmIeFNIAx8DgHxhAzQD0GLTKJ76PqVBsLNozc1hBAmfCXqIMeFZEYAHMzOaDS1LBIY1My6Jh2MdWI6zvdajxfOIxsgQnvLD5JHuHCnnDDQcM7UNu7/eRE6btffNiF4nevTCHDziSe8q8KmPhRRST0tQCNHzIBK/meBcou9UdRY9IkSPEuHAQT+Qd9MEHAdTdQdh41WB9kjbtZlDCuSVwtEhWOhoE6qAphnMUHZUamyhSb9ycbKlwcXJBfWn+/4CFGtyIQwWwbUeA13lAgj5UrcgKo6vBz61k2BcsTCj+GpB0Gw52Wr3vcH2MKDw7s4UFAgCeodsApUO58ZWS7FH6gh9Wz7FP8xkr3Ji2ZGl2WPZ2t8OCaKs09mQMOO/Col/vyskLHt0xkXCFti1rM5itvZp0+m0ez2WdYtUHb9yaMjovw+4qdZVSrqBZjnQqF2/mMvK9Kv6SjWimA8yjEFN34vCk/0mj4Uxqnll6ZWpqGaQLpTd/TDXZqlKFV6Kv+ahJsv6nXtLeVppFtW7DPaVCgDaV2ZgjLaTZipg1z1PjN0lQnbaark62x1i1EvXdyBouve+Z/bBGbUaVZlXi3mL4ierdZM4fSgJLc1b0ZvQMG8uO7Q4lf8OX7tZhys19nErc94LWc2s2IiGDxK11f1mXbtIkKF+nW2ue54/cy4OvYcwlr/yZcbDSNJ3Jf9/Vq7WLBUskcfClMKbAqR8KY6lMtquk3gWF+b/ZTVbZukq/iXUSro68TUO9EgVwwW5OzoAss6x+DFFoxofdCGg6RFW9yw7U/5RdK+87alPKABaQtVHtr7qlt1XtIf+Z+v71X/4p+BfJLgC8UsIWXz1q+e+6phoac1q4bmTN9BI0MDjWc1j3oBDMslqqV+XpjnpH+y2E53NHYBaOTvRq9TdVw205tB4oCbUoGq6WOUd+nUHrCLSrjW7XUTsHVJ34tEq5Xgo6QlPZT3bi0RDonqUD+Las52d11vGRoDX1Vs+1Lu7b/HQvzJmI4hHD82MD7UqlgblNQZk2FWxHkXC+fUbFyYSQW8igd1Eoi+mdah5cNXpl8Fk5/MijH2KBHVd6jF2fOkzDcwVQ71v4nMoo7I/wpciBBvxJVCWenwHzlHNC7S3Goz6EigrPq8t0ajZGTj6K6C6vBenBxfsGKO7vTXnXKpFf7UN6pquZAfeXdO3/+VT+306ul/icP8+xN3H9++dRB//Dw==</diagram></mxfile>
<mxfile modified="2019-11-12T12:32:01.670Z" host="www.draw.io" agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.87 Safari/537.36" etag="y3SiWZxfgyiBVglI6z8O" version="12.2.4" type="device" pages="1"><diagram name="Page-1" id="b33cb84f-bf7a-9ccf-f142-242d16432e5d">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</diagram></mxfile>
Binary file modified doc/technical/mapview/MapView.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 4 additions & 4 deletions mapview/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlinx-serialization'

def version = "1.0.3"
def version = "1.0.4"

androidExtensions {
experimental = true
Expand Down Expand Up @@ -56,9 +56,9 @@ dependencies {
testImplementation 'junit:junit:4.12'
testImplementation 'org.robolectric:robolectric:4.3'
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.1'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.1'
implementation "org.jetbrains.kotlinx:kotlinx-serialization-runtime:0.11.0"
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.2'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.2'
implementation "org.jetbrains.kotlinx:kotlinx-serialization-runtime:0.13.0"
}
repositories {
mavenCentral()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@ package com.peterlaurence.mapview.core

import android.graphics.Bitmap
import android.graphics.BitmapFactory
import kotlinx.coroutines.*
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.channels.ReceiveChannel
import kotlinx.coroutines.channels.SendChannel
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.single
import kotlinx.coroutines.launch
import kotlinx.coroutines.selects.select


Expand All @@ -24,16 +26,17 @@ import kotlinx.coroutines.selects.select
* ---------------- [*********] <----------------------------------------------------- | | worker | | |
* | | | -------- | |
* ↓ | | ________ | |
* _____________________ | tileStatus | | worker | | |
* _____________________ | tileSpecs | | worker | | |
* | TileCanvasViewModel | | _____________________ <---- [**********] <---- | -------- | |
* --------------------- ----> [*********] ----> | tileCollectorKernel | | ________ | |
* tileSpecs | --------------------- ----> [**********] ----> | | worker | | |
* | tileStatus | -------- | |
* | tileSpecs | -------- | |
* | |____________| |
* | worker pool |
* | |
* ---------------------------------------------------------------------
* ```
* This architecture is an example of Communicating Sequential Processes (CSP).
*
* @author peterLaurence on 22/06/19
*/
Expand All @@ -42,38 +45,34 @@ class TileCollector(private val workerCount: Int) {
/**
* Sets up the tile collector machinery. The architecture is inspired from
* [Kotlin Conf 2018](https://www.youtube.com/watch?v=a3agLJQ6vt8).
* @param [tileSpecs] channel of [TileSpec], which capacity should be [Channel.CONFLATED].
* It support back-pressure, and avoids deadlock in CSP taking into account recommendations of
* this [article](https://medium.com/@elizarov/deadlocks-in-non-hierarchical-csp-e5910d137cc),
* which is from the same author.
*
* @param [tileSpecs] channel of [TileSpec], which capacity should be [Channel.RENDEZVOUS].
* @param [tilesOutput] channel of [Tile], which should be set as [Channel.RENDEZVOUS].
*/
fun CoroutineScope.collectTiles(tileSpecs: ReceiveChannel<List<TileSpec>>,
fun CoroutineScope.collectTiles(tileSpecs: ReceiveChannel<TileSpec>,
tilesOutput: SendChannel<Tile>,
tileStreamProvider: TileStreamProvider,
bitmapFlow: Flow<Bitmap>) {
val tilesToDownload = Channel<TileStatus>(capacity = Channel.RENDEZVOUS)
val tilesDownloadedFromWorker = Channel<TileStatus>(capacity = Channel.UNLIMITED)
val tilesToDownload = Channel<TileSpec>(capacity = Channel.RENDEZVOUS)
val tilesDownloadedFromWorker = Channel<TileSpec>(capacity = 1)

repeat(workerCount) { worker(tilesToDownload, tilesDownloadedFromWorker, tilesOutput, tileStreamProvider, bitmapFlow) }
tileCollectorKernel(tileSpecs, tilesToDownload, tilesDownloadedFromWorker)
}

private fun CoroutineScope.worker(tilesToDownload: ReceiveChannel<TileStatus>,
tilesDownloaded: SendChannel<TileStatus>,
private fun CoroutineScope.worker(tilesToDownload: ReceiveChannel<TileSpec>,
tilesDownloaded: SendChannel<TileSpec>,
tilesOutput: SendChannel<Tile>,
tileStreamProvider: TileStreamProvider,
bitmapFlow: Flow<Bitmap>) = launch(Dispatchers.IO) {

val bitmapLoadingOptions = BitmapFactory.Options()
bitmapLoadingOptions.inPreferredConfig = Bitmap.Config.RGB_565

for (tileStatus in tilesToDownload) {
/* If it was cancelled, do nothing and send back the TileSpec as is */
if (tileStatus.cancelled) {
tilesDownloaded.send(tileStatus)
continue
}

val spec = tileStatus.spec

for (spec in tilesToDownload) {
val i = tileStreamProvider.getTileStream(spec.row, spec.col, spec.zoom)

if (spec.subSample > 0) {
Expand All @@ -97,44 +96,33 @@ class TileCollector(private val workerCount: Int) {
} catch (e: Exception) {
// maybe retry
} finally {
tilesDownloaded.send(tileStatus)
tilesDownloaded.send(spec)
i?.close()
}
}
}

private fun CoroutineScope.tileCollectorKernel(tileSpecs: ReceiveChannel<List<TileSpec>>,
tilesToDownload: SendChannel<TileStatus>,
tilesDownloadedFromWorker: ReceiveChannel<TileStatus>) = launch(Dispatchers.Default) {
private fun CoroutineScope.tileCollectorKernel(tileSpecs: ReceiveChannel<TileSpec>,
tilesToDownload: SendChannel<TileSpec>,
tilesDownloadedFromWorker: ReceiveChannel<TileSpec>) = launch(Dispatchers.Default) {

val tilesBeingProcessed = mutableListOf<TileStatus>()
val tilesBeingProcessed = mutableListOf<TileSpec>()

while (true) {
select<Unit> {
tilesDownloadedFromWorker.onReceive {
tilesBeingProcessed.remove(it)
}
tileSpecs.onReceive {
for (loc in it) {
if (!tilesBeingProcessed.any { status -> status.spec == loc }) {
/* Add it to the list of locations being processed */
val status = TileStatus(loc)
tilesBeingProcessed.add(status)
if (!tilesBeingProcessed.any { spec -> spec == it }) {
/* Add it to the list of locations being processed */
tilesBeingProcessed.add(it)

/* Now download the tile */
tilesToDownload.send(status)
}
/* Now download the tile */
tilesToDownload.send(it)
}
for (status in tilesBeingProcessed) {
if (!it.contains(status.spec)) {
status.cancelled = true
}
}
}

tilesDownloadedFromWorker.onReceive {
tilesBeingProcessed.remove(it)
}
}
}
}

data class TileStatus(val spec: TileSpec, @Volatile var cancelled: Boolean = false)
}
Loading

0 comments on commit c423e02

Please sign in to comment.