Skip to content

Commit

Permalink
Implement Parallelized Map
Browse files Browse the repository at this point in the history
- Optimize Database search API
  • Loading branch information
ndegwamartin committed Sep 7, 2024
1 parent d9653b6 commit 2fc407c
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 4 deletions.
8 changes: 8 additions & 0 deletions engine/src/main/java/com/google/android/fhir/Util.kt
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ import java.time.ZoneId
import java.time.format.DateTimeFormatter
import java.util.Date
import java.util.Locale
import kotlinx.coroutines.async
import kotlinx.coroutines.awaitAll
import kotlinx.coroutines.coroutineScope
import org.hl7.fhir.r4.model.OperationOutcome
import org.hl7.fhir.r4.model.Resource
import org.hl7.fhir.r4.model.ResourceType
Expand Down Expand Up @@ -82,3 +85,8 @@ internal const val ucumUrl = "http://unitsofmeasure.org"

internal fun percentOf(value: Number, total: Number) =
if (total == 0) 0.0 else value.toDouble() / total.toDouble()

/** Implementation of a parallelized map */
suspend fun <A, B> Iterable<A>.pmap(f: suspend (A) -> B): List<B> = coroutineScope {
map { async { f(it) } }.awaitAll()
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import com.google.android.fhir.db.impl.dao.ReverseIncludeSearchResult
import com.google.android.fhir.db.impl.entities.ResourceEntity
import com.google.android.fhir.index.ResourceIndexer
import com.google.android.fhir.logicalId
import com.google.android.fhir.pmap
import com.google.android.fhir.search.SearchQuery
import com.google.android.fhir.toLocalChange
import java.time.Instant
Expand Down Expand Up @@ -205,7 +206,7 @@ internal class DatabaseImpl(
query: SearchQuery,
): List<ResourceWithUUID<R>> {
return db.withTransaction {
resourceDao.getResources(SimpleSQLiteQuery(query.query, query.args.toTypedArray())).map {
resourceDao.getResources(SimpleSQLiteQuery(query.query, query.args.toTypedArray())).pmap {
ResourceWithUUID(it.uuid, iParser.parseResource(it.serializedResource) as R)
}
}
Expand All @@ -217,7 +218,7 @@ internal class DatabaseImpl(
return db.withTransaction {
resourceDao
.getForwardReferencedResources(SimpleSQLiteQuery(query.query, query.args.toTypedArray()))
.map {
.pmap {
ForwardIncludeSearchResult(
it.matchingIndex,
it.baseResourceUUID,
Expand All @@ -233,7 +234,7 @@ internal class DatabaseImpl(
return db.withTransaction {
resourceDao
.getReverseReferencedResources(SimpleSQLiteQuery(query.query, query.args.toTypedArray()))
.map {
.pmap {
ReverseIncludeSearchResult(
it.matchingIndex,
it.baseResourceTypeAndId,
Expand Down
23 changes: 22 additions & 1 deletion engine/src/test/java/com/google/android/fhir/UtilTest.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2022-2023 Google LLC
* Copyright 2022-2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -19,6 +19,9 @@ package com.google.android.fhir
import android.os.Build
import com.google.common.truth.Truth.assertThat
import junit.framework.TestCase
import kotlin.system.measureTimeMillis
import kotlinx.coroutines.delay
import kotlinx.coroutines.runBlocking
import org.hl7.fhir.r4.model.IdType
import org.hl7.fhir.r4.model.OperationOutcome
import org.hl7.fhir.r4.model.Patient
Expand Down Expand Up @@ -111,6 +114,24 @@ class UtilTest : TestCase() {
assertThat(percentOf(25, 50)).isEqualTo(0.5)
}

@Test
fun `pmap() should execute mapping tasks in parallel`() = runBlocking {
val numberList = listOf(2, 3)
var squaredNumberList: List<Int>

val timeTaken = measureTimeMillis {
squaredNumberList =
numberList.pmap {
delay(1000L)
it * 2
}
}
assertTrue(squaredNumberList.isNotEmpty())
assertThat(squaredNumberList.first()).isEqualTo(4)
assertThat(squaredNumberList.last()).isEqualTo(6)
assertTrue(timeTaken < 2000)
}

companion object {
val TEST_OPERATION_OUTCOME_ERROR = OperationOutcome()
val TEST_OPERATION_OUTCOME_INFO = OperationOutcome()
Expand Down

0 comments on commit 2fc407c

Please sign in to comment.