Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Batch searching when list might be large or when count is not defined #3456

Merged
merged 4 commits into from
Sep 19, 2024

Conversation

LZRS
Copy link
Contributor

@LZRS LZRS commented Aug 20, 2024

IMPORTANT: Where possible all PRs must be linked to a Github issue

Fixes #3440

Engineer Checklist

  • I have written Unit tests for any new feature(s) and edge cases for bug fixes
  • I have added any strings visible on UI components to the strings.xml file
  • I have updated the CHANGELOG.md file for any notable changes to the codebase
  • I have run ./gradlew spotlessApply and ./gradlew spotlessCheck to check my code follows the project's style guide
  • I have built and run the FHIRCore app to verify my change fixes the issue and/or does not break the app
  • I have checked that this PR does NOT introduce breaking changes that require an update to Content and/or Configs? If it does add a sample here or a link to exactly what changes need to be made to the content.

Code Reviewer Checklist

  • I have verified Unit tests have been written for any new feature(s) and edge cases
  • I have verified any strings visible on UI components are in the strings.xml file
  • I have verifed the CHANGELOG.md file has any notable changes to the codebase
  • I have verified the solution has been implemented in a configurable and generic way for reuseable components
  • I have built and run the FHIRCore app to verify the change fixes the issue and/or does not break the app

@LZRS LZRS self-assigned this Aug 20, 2024
Copy link

codecov bot commented Aug 20, 2024

Codecov Report

Attention: Patch coverage is 66.66667% with 13 lines in your changes missing coverage. Please review.

Project coverage is 27.2%. Comparing base (115c4f4) to head (6ee690d).
Report is 6 commits behind head on main.

Files Patch % Lines
...rcore/engine/util/extension/FhirEngineExtension.kt 66.6% 4 Missing and 3 partials ⚠️
...er/fhircore/engine/data/local/DefaultRepository.kt 87.5% 1 Missing ⚠️
...ster/fhircore/engine/p2p/dao/BaseP2PTransferDao.kt 0.0% 1 Missing ⚠️
...fhircore/engine/task/FhirCompleteCarePlanWorker.kt 0.0% 1 Missing ⚠️
...hircore/engine/util/extension/MeasureExtensions.kt 0.0% 1 Missing ⚠️
...e/quest/ui/questionnaire/QuestionnaireViewModel.kt 0.0% 1 Missing ⚠️
...st/ui/report/measure/worker/MeasureReportWorker.kt 0.0% 1 Missing ⚠️
Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff            @@
##              main   #3456     +/-   ##
=========================================
- Coverage     27.2%   27.2%   -0.1%     
- Complexity     742     746      +4     
=========================================
  Files          276     276             
  Lines        13811   13903     +92     
  Branches      2504    2524     +20     
=========================================
+ Hits          3764    3788     +24     
- Misses        9540    9593     +53     
- Partials       507     522     +15     
Flag Coverage Δ
engine 64.3% <70.2%> (-0.4%) ⬇️
geowidget 11.5% <ø> (+<0.1%) ⬆️
quest 5.5% <0.0%> (-0.1%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files Coverage Δ
...ster/fhircore/engine/task/FhirCarePlanGenerator.kt 78.1% <100.0%> (ø)
...tregister/fhircore/engine/task/FhirResourceUtil.kt 85.8% <100.0%> (ø)
...hircore/engine/util/extension/ResourceExtension.kt 67.5% <100.0%> (+0.3%) ⬆️
...er/fhircore/engine/data/local/DefaultRepository.kt 65.0% <87.5%> (ø)
...ster/fhircore/engine/p2p/dao/BaseP2PTransferDao.kt 72.4% <0.0%> (ø)
...fhircore/engine/task/FhirCompleteCarePlanWorker.kt 73.9% <0.0%> (ø)
...hircore/engine/util/extension/MeasureExtensions.kt 50.0% <0.0%> (ø)
...e/quest/ui/questionnaire/QuestionnaireViewModel.kt 2.9% <0.0%> (+0.1%) ⬆️
...st/ui/report/measure/worker/MeasureReportWorker.kt 0.0% <0.0%> (ø)
...rcore/engine/util/extension/FhirEngineExtension.kt 58.8% <66.6%> (+1.2%) ⬆️

... and 1 file with indirect coverage changes

Comment on lines +104 to +115
val result = mutableListOf<SearchResult<R>>()
var offset = search.from ?: 0
val pageCount = 100
do {
search.from = offset
search.count = pageCount
val searchResults = this.search<R>(search)
result += searchResults
offset += searchResults.size
} while (searchResults.size == pageCount)

result
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this @LZRS.

I have a few questions and comments on this implementation.

The decision to load this data in batches sounds reasonable, however, based on this implementation I believe the gain would be negligible or there would be no gain at all. Technically, the data will still be cached in memory inside the loop. This differs from the approach where we would load and process the data in batches. Data processing should happen after fetching each batch to improve the app responsiveness, otherwise, there are some drawbacks with batching including:

  1. Each batch fetch requires a new database query, introducing overhead. The overhead of executing smaller queries may outweigh the benefit of lower memory.

  2. Using OFFSET requires the database to skip over records
    before returning the batch. A larger offset would require scanning and discarding many rows thus if indexing is not done properly, this will impact fetching data in batches.

@LZRS Would it be possible to measure the performance impact introduced by this implementation for comparison?

The paging3 library loads data in batches and allows for data processing with each fetch.

cc @ndegwamartin @pld

Copy link
Contributor Author

@LZRS LZRS Aug 27, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, generally, I think the performance gains would probably be negligible (in one of our cases, a difference of 20ms) especially when assuming only our query of interest would be running a single time. I think the significance of these changes would come about when we have multiple queries from different coroutines/threads.

Assuming for example we have a background long running operation accessing the db, and in the UI someone goes to a page that to render also requires a db fetch. Instead of waiting for the long running background operation to finish, the db fetch for the UI page can get queued in between the batches for the long running background. Looking to also add integration tests on the same

The changes here would ensure that no single query(in batch) would take more than a couple of milliseconds, a long running query would still take long to be loaded (as it's split and cached in memory) but it would allow space for other queries to also get run.

I also agree that the best case would be data processing after fetching each batch although that would be quite tasking to implement, I feel.

In terms of MalawiCore, it improved the app's performance from here to here.
We'll working on similar tests for FhirCore.

Use of paging3 to load would be the recommended approach but it would also need approval from the Google's sdk team that would also take time, I think

Note:

Room will only perform at most one transaction at a time, additional transactions are queued and executed on a first come, first serve order.

@LZRS LZRS force-pushed the 3440-batch-fetch-search-count-all branch from 856f86c to 4de7da5 Compare August 26, 2024 15:51
@LZRS LZRS force-pushed the 3440-batch-fetch-search-count-all branch 2 times, most recently from 29b1043 to 6ee690d Compare August 28, 2024 13:00
@LZRS LZRS changed the base branch from main to fix-register-filters September 18, 2024 14:41
@LZRS LZRS force-pushed the 3440-batch-fetch-search-count-all branch from 6ee690d to 345552a Compare September 18, 2024 15:37
@LZRS LZRS marked this pull request as ready for review September 18, 2024 15:38
@LZRS LZRS requested a review from ellykits September 18, 2024 15:38
@LZRS LZRS force-pushed the 3440-batch-fetch-search-count-all branch from 345552a to 5966fe5 Compare September 18, 2024 15:44
@ellykits ellykits merged commit 05f3476 into fix-register-filters Sep 19, 2024
@ellykits ellykits deleted the 3440-batch-fetch-search-count-all branch September 19, 2024 14:22
dubdabasoduba added a commit that referenced this pull request Sep 20, 2024
* Refactor register filter with REL tags

Signed-off-by: Elly Kitoto <[email protected]>

* Update default pageSize to 15

Signed-off-by: Elly Kitoto <[email protected]>

* Fix loading locations on map

Signed-off-by: Elly Kitoto <[email protected]>

* Refactor data structure used on base resource search results

Signed-off-by: Elly Kitoto <[email protected]>

* Refactor code

Signed-off-by: Elly Kitoto <[email protected]>

* Delete unnecessary code

Signed-off-by: Elly Kitoto <[email protected]>

* Refactor retrieving related resources

Signed-off-by: Elly Kitoto <[email protected]>

* Optimize data structures and perform parallel processing

Signed-off-by: Elly Kitoto <[email protected]>

* Use recent version of rules engine library

Signed-off-by: Elly Kitoto <[email protected]>

* Refactor implementation for decoding image resources to bitmap

Signed-off-by: Elly Kitoto <[email protected]>

* Fix related resource count on register

Signed-off-by: Elly Kitoto <[email protected]>

* Fix loading related resources

This fix ensures all the nested related resources are loaded too.

Signed-off-by: Elly Kitoto <[email protected]>

* Batch related resource queries

Signed-off-by: Elly Kitoto <[email protected]>

* Map resources to RepositoryResourceData with async map

Signed-off-by: Elly Kitoto <[email protected]>

* Make infinite scroll the default register behavior

Signed-off-by: Elly Kitoto <[email protected]>

* Disable automatic intialization of emoji2

A lot of memory was used in heap during the allocation. Emojis are not
used in the app so intializing them automatically is unnecessary.

Signed-off-by: Elly Kitoto <[email protected]>

* ⬆️ Update the map box and kujaku versions

* Run spotlessApply

Signed-off-by: Elly Kitoto <[email protected]>

* Update tests for displaying images (#3506)

* Refactor load images tests for different views.

Signed-off-by: Lentumunai-Mark <[email protected]>

* Remove unutilized imports.

Signed-off-by: Lentumunai-Mark <[email protected]>

* Run spotlessApply

Signed-off-by: Elly Kitoto <[email protected]>
Signed-off-by: Lentumunai-Mark <[email protected]>

* Refactor load images tests for different views.

Signed-off-by: Lentumunai-Mark <[email protected]>

* Resolve conflicts.

Signed-off-by: Lentumunai-Mark <[email protected]>

---------

Signed-off-by: Lentumunai-Mark <[email protected]>
Signed-off-by: Elly Kitoto <[email protected]>

* Refactor navigation to GeowidgetLauncher workflow

Signed-off-by: Elly Kitoto <[email protected]>

* Load map data in batches (#3511)

* Load map data in batches

Signed-off-by: Elly Kitoto <[email protected]>

* Update observer

Signed-off-by: Elly Kitoto <[email protected]>

* Deactivate infinite scroll by default

Signed-off-by: Elly Kitoto <[email protected]>

---------

Signed-off-by: Elly Kitoto <[email protected]>

* Fix failing tests

Signed-off-by: Elly Kitoto <[email protected]>

* Batch searching when list might be large or when count is not defined (#3456)

* Fetch search results in batches for when loading all

* Fix infinite loop for mocks with FhirEngine#search in tests

* Add comparable FhirEngine#search vs batchedSearch integration tests

* Run spotlessApply

Signed-off-by: Elly Kitoto <[email protected]>

* Fix Geowidget tests

Signed-off-by: Elly Kitoto <[email protected]>

* Fix spotlessCheck

Signed-off-by: Elly Kitoto <[email protected]>

* Add missing import

Signed-off-by: Elly Kitoto <[email protected]>

* Fix rules execution before map render

Signed-off-by: Elly Kitoto <[email protected]>

* - Update android manifest to use exported values

* Prevent leaking map features via viewmodel

Signed-off-by: Elly Kitoto <[email protected]>

* Format code

Signed-off-by: Elly Kitoto <[email protected]>

* Only search map features via keyboard action

We need to reload all features when the search term is reset

Signed-off-by: Elly Kitoto <[email protected]>

---------

Signed-off-by: Elly Kitoto <[email protected]>
Signed-off-by: Lentumunai-Mark <[email protected]>
Co-authored-by: Benjamin Mwalimu <[email protected]>
Co-authored-by: Lentumunai Mark <[email protected]>
Co-authored-by: L≡ZRS <[email protected]>
qiarie pushed a commit that referenced this pull request Jan 15, 2025
* Refactor register filter with REL tags

Signed-off-by: Elly Kitoto <[email protected]>

* Update default pageSize to 15

Signed-off-by: Elly Kitoto <[email protected]>

* Fix loading locations on map

Signed-off-by: Elly Kitoto <[email protected]>

* Refactor data structure used on base resource search results

Signed-off-by: Elly Kitoto <[email protected]>

* Refactor code

Signed-off-by: Elly Kitoto <[email protected]>

* Delete unnecessary code

Signed-off-by: Elly Kitoto <[email protected]>

* Refactor retrieving related resources

Signed-off-by: Elly Kitoto <[email protected]>

* Optimize data structures and perform parallel processing

Signed-off-by: Elly Kitoto <[email protected]>

* Use recent version of rules engine library

Signed-off-by: Elly Kitoto <[email protected]>

* Refactor implementation for decoding image resources to bitmap

Signed-off-by: Elly Kitoto <[email protected]>

* Fix related resource count on register

Signed-off-by: Elly Kitoto <[email protected]>

* Fix loading related resources

This fix ensures all the nested related resources are loaded too.

Signed-off-by: Elly Kitoto <[email protected]>

* Batch related resource queries

Signed-off-by: Elly Kitoto <[email protected]>

* Map resources to RepositoryResourceData with async map

Signed-off-by: Elly Kitoto <[email protected]>

* Make infinite scroll the default register behavior

Signed-off-by: Elly Kitoto <[email protected]>

* Disable automatic intialization of emoji2

A lot of memory was used in heap during the allocation. Emojis are not
used in the app so intializing them automatically is unnecessary.

Signed-off-by: Elly Kitoto <[email protected]>

* ⬆️ Update the map box and kujaku versions

* Run spotlessApply

Signed-off-by: Elly Kitoto <[email protected]>

* Update tests for displaying images (#3506)

* Refactor load images tests for different views.

Signed-off-by: Lentumunai-Mark <[email protected]>

* Remove unutilized imports.

Signed-off-by: Lentumunai-Mark <[email protected]>

* Run spotlessApply

Signed-off-by: Elly Kitoto <[email protected]>
Signed-off-by: Lentumunai-Mark <[email protected]>

* Refactor load images tests for different views.

Signed-off-by: Lentumunai-Mark <[email protected]>

* Resolve conflicts.

Signed-off-by: Lentumunai-Mark <[email protected]>

---------

Signed-off-by: Lentumunai-Mark <[email protected]>
Signed-off-by: Elly Kitoto <[email protected]>

* Refactor navigation to GeowidgetLauncher workflow

Signed-off-by: Elly Kitoto <[email protected]>

* Load map data in batches (#3511)

* Load map data in batches

Signed-off-by: Elly Kitoto <[email protected]>

* Update observer

Signed-off-by: Elly Kitoto <[email protected]>

* Deactivate infinite scroll by default

Signed-off-by: Elly Kitoto <[email protected]>

---------

Signed-off-by: Elly Kitoto <[email protected]>

* Fix failing tests

Signed-off-by: Elly Kitoto <[email protected]>

* Batch searching when list might be large or when count is not defined (#3456)

* Fetch search results in batches for when loading all

* Fix infinite loop for mocks with FhirEngine#search in tests

* Add comparable FhirEngine#search vs batchedSearch integration tests

* Run spotlessApply

Signed-off-by: Elly Kitoto <[email protected]>

* Fix Geowidget tests

Signed-off-by: Elly Kitoto <[email protected]>

* Fix spotlessCheck

Signed-off-by: Elly Kitoto <[email protected]>

* Add missing import

Signed-off-by: Elly Kitoto <[email protected]>

* Fix rules execution before map render

Signed-off-by: Elly Kitoto <[email protected]>

* - Update android manifest to use exported values

* Prevent leaking map features via viewmodel

Signed-off-by: Elly Kitoto <[email protected]>

* Format code

Signed-off-by: Elly Kitoto <[email protected]>

* Only search map features via keyboard action

We need to reload all features when the search term is reset

Signed-off-by: Elly Kitoto <[email protected]>

---------

Signed-off-by: Elly Kitoto <[email protected]>
Signed-off-by: Lentumunai-Mark <[email protected]>
Co-authored-by: Benjamin Mwalimu <[email protected]>
Co-authored-by: Lentumunai Mark <[email protected]>
Co-authored-by: L≡ZRS <[email protected]>
asad-zaman pushed a commit to Mpower-social/fhircore-smart-health-bd that referenced this pull request Jan 20, 2025
* Refactor register filter with REL tags

Signed-off-by: Elly Kitoto <[email protected]>

* Update default pageSize to 15

Signed-off-by: Elly Kitoto <[email protected]>

* Fix loading locations on map

Signed-off-by: Elly Kitoto <[email protected]>

* Refactor data structure used on base resource search results

Signed-off-by: Elly Kitoto <[email protected]>

* Refactor code

Signed-off-by: Elly Kitoto <[email protected]>

* Delete unnecessary code

Signed-off-by: Elly Kitoto <[email protected]>

* Refactor retrieving related resources

Signed-off-by: Elly Kitoto <[email protected]>

* Optimize data structures and perform parallel processing

Signed-off-by: Elly Kitoto <[email protected]>

* Use recent version of rules engine library

Signed-off-by: Elly Kitoto <[email protected]>

* Refactor implementation for decoding image resources to bitmap

Signed-off-by: Elly Kitoto <[email protected]>

* Fix related resource count on register

Signed-off-by: Elly Kitoto <[email protected]>

* Fix loading related resources

This fix ensures all the nested related resources are loaded too.

Signed-off-by: Elly Kitoto <[email protected]>

* Batch related resource queries

Signed-off-by: Elly Kitoto <[email protected]>

* Map resources to RepositoryResourceData with async map

Signed-off-by: Elly Kitoto <[email protected]>

* Make infinite scroll the default register behavior

Signed-off-by: Elly Kitoto <[email protected]>

* Disable automatic intialization of emoji2

A lot of memory was used in heap during the allocation. Emojis are not
used in the app so intializing them automatically is unnecessary.

Signed-off-by: Elly Kitoto <[email protected]>

* ⬆️ Update the map box and kujaku versions

* Run spotlessApply

Signed-off-by: Elly Kitoto <[email protected]>

* Update tests for displaying images (opensrp#3506)

* Refactor load images tests for different views.

Signed-off-by: Lentumunai-Mark <[email protected]>

* Remove unutilized imports.

Signed-off-by: Lentumunai-Mark <[email protected]>

* Run spotlessApply

Signed-off-by: Elly Kitoto <[email protected]>
Signed-off-by: Lentumunai-Mark <[email protected]>

* Refactor load images tests for different views.

Signed-off-by: Lentumunai-Mark <[email protected]>

* Resolve conflicts.

Signed-off-by: Lentumunai-Mark <[email protected]>

---------

Signed-off-by: Lentumunai-Mark <[email protected]>
Signed-off-by: Elly Kitoto <[email protected]>

* Refactor navigation to GeowidgetLauncher workflow

Signed-off-by: Elly Kitoto <[email protected]>

* Load map data in batches (opensrp#3511)

* Load map data in batches

Signed-off-by: Elly Kitoto <[email protected]>

* Update observer

Signed-off-by: Elly Kitoto <[email protected]>

* Deactivate infinite scroll by default

Signed-off-by: Elly Kitoto <[email protected]>

---------

Signed-off-by: Elly Kitoto <[email protected]>

* Fix failing tests

Signed-off-by: Elly Kitoto <[email protected]>

* Batch searching when list might be large or when count is not defined (opensrp#3456)

* Fetch search results in batches for when loading all

* Fix infinite loop for mocks with FhirEngine#search in tests

* Add comparable FhirEngine#search vs batchedSearch integration tests

* Run spotlessApply

Signed-off-by: Elly Kitoto <[email protected]>

* Fix Geowidget tests

Signed-off-by: Elly Kitoto <[email protected]>

* Fix spotlessCheck

Signed-off-by: Elly Kitoto <[email protected]>

* Add missing import

Signed-off-by: Elly Kitoto <[email protected]>

* Fix rules execution before map render

Signed-off-by: Elly Kitoto <[email protected]>

* - Update android manifest to use exported values

* Prevent leaking map features via viewmodel

Signed-off-by: Elly Kitoto <[email protected]>

* Format code

Signed-off-by: Elly Kitoto <[email protected]>

* Only search map features via keyboard action

We need to reload all features when the search term is reset

Signed-off-by: Elly Kitoto <[email protected]>

---------

Signed-off-by: Elly Kitoto <[email protected]>
Signed-off-by: Lentumunai-Mark <[email protected]>
Co-authored-by: Benjamin Mwalimu <[email protected]>
Co-authored-by: Lentumunai Mark <[email protected]>
Co-authored-by: L≡ZRS <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Reduce transaction(hog) time for GET that might return large results by fetching in batches
2 participants