Skip to content

Commit

Permalink
cache some complex operations
Browse files Browse the repository at this point in the history
Signed-off-by: Pablo <[email protected]>
  • Loading branch information
Balcan authored and andresmr committed Feb 13, 2024
1 parent 23d412c commit cc20ed7
Show file tree
Hide file tree
Showing 2 changed files with 102 additions and 73 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,6 @@

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.Transformations;
import androidx.paging.DataSource;
import androidx.paging.LivePagedListBuilder;
import androidx.paging.PagedList;
import androidx.paging.Pager;
import androidx.paging.PagingData;
import androidx.paging.PagingDataTransforms;
import androidx.paging.PagingLiveData;

import org.dhis2.R;
import org.dhis2.bindings.ExtensionsKt;
Expand All @@ -31,6 +22,7 @@
import org.dhis2.commons.filters.data.FilterPresenter;
import org.dhis2.commons.filters.sorting.SortingItem;
import org.dhis2.commons.network.NetworkUtils;
import org.dhis2.commons.prefs.PreferenceProvider;
import org.dhis2.commons.reporting.CrashReportController;
import org.dhis2.commons.resources.ResourceManager;
import org.dhis2.data.dhislogic.DhisEnrollmentUtils;
Expand Down Expand Up @@ -102,11 +94,6 @@
import io.reactivex.Flowable;
import io.reactivex.Observable;
import io.reactivex.Single;
import kotlin.Unit;
import kotlin.coroutines.Continuation;
import kotlinx.coroutines.ExecutorsKt;
import kotlinx.coroutines.flow.Flow;
import kotlinx.coroutines.flow.FlowCollector;

public class SearchRepositoryImpl implements SearchRepository {

Expand All @@ -128,6 +115,14 @@ public class SearchRepositoryImpl implements SearchRepository {
private ThemeManager themeManager;
private HashSet<String> fetchedTeiUids = new HashSet<>();
private TeiDownloader teiDownloader;
private HashMap<String, Program> programCache = new HashMap<>();
private HashMap<String, String> orgUnitNameCache = new HashMap<>();

private HashMap<String, String> profilePictureCache = new HashMap<>();

private HashMap<String, List<String>> attributesUidsCache = new HashMap();

private HashMap<String, List<String>> trackedEntityTypeAttributesUidsCache = new HashMap();

SearchRepositoryImpl(String teiType,
@Nullable String initialProgram,
Expand Down Expand Up @@ -162,6 +157,7 @@ public class SearchRepositoryImpl implements SearchRepository {
resources);
}


@Override
public Observable<List<Program>> programsWithRegistration(String programTypeId) {
return d2.organisationUnitModule().organisationUnits().byOrganisationUnitScope(OrganisationUnit.Scope.SCOPE_DATA_CAPTURE).get()
Expand Down Expand Up @@ -302,7 +298,7 @@ public Observable<Pair<String, String>> saveToEnroll(@NonNull String teiType,
.organisationUnit(orgUnit)
.build())
.map(enrollmentUid -> {
boolean displayIncidentDate = d2.programModule().programs().uid(programUid).blockingGet().displayIncidentDate();
boolean displayIncidentDate = getProgram(programUid).displayIncidentDate();
Date enrollmentDateNoTime = DateUtils.getInstance().getNextPeriod(PeriodType.Daily, enrollmentDate, 0);
d2.enrollmentModule().enrollments().uid(enrollmentUid).setEnrollmentDate(enrollmentDateNoTime);
if (displayIncidentDate) {
Expand Down Expand Up @@ -338,7 +334,7 @@ private void setEnrollmentInfo(SearchTeiModel searchTei) {
if (enrollments.indexOf(enrollment) == 0)
searchTei.resetEnrollments();
searchTei.addEnrollment(enrollment);
Program program = d2.programModule().programs().byUid().eq(enrollment.program()).one().blockingGet();
Program program = getProgram(enrollment.program());
if (program.displayFrontPageList()) {
searchTei.addProgramInfo(program);
}
Expand Down Expand Up @@ -480,8 +476,8 @@ private void setRelationshipsInfo(@NonNull SearchTeiModel searchTeiModel, Progra
RelationshipOwnerType.TEI,
fromValues,
toValues,
ExtensionsKt.profilePicturePath(fromTei, d2, selectedProgram.uid()),
ExtensionsKt.profilePicturePath(toTei, d2, selectedProgram.uid()),
profilePicturePath(fromTei, selectedProgram.uid()),
profilePicturePath(toTei, selectedProgram.uid()),
getTeiDefaultRes(fromTei),
getTeiDefaultRes(toTei),
-1,
Expand All @@ -493,6 +489,45 @@ private void setRelationshipsInfo(@NonNull SearchTeiModel searchTeiModel, Progra
searchTeiModel.setRelationships(relationshipViewModels);
}

private String profilePicturePath(TrackedEntityInstance tei, String programUid){
if(!profilePictureCache.containsKey(tei.uid())){
profilePictureCache.put(tei.uid(),ExtensionsKt.profilePicturePath(tei, d2, programUid));
}
return profilePictureCache.get(tei.uid());
}

private List<String> getProgramAttributeUids(String programUid) {
if(!attributesUidsCache.containsKey(programUid)){
List<String> attributeUids = new ArrayList<>();
List<ProgramTrackedEntityAttribute> programTrackedEntityAttributes = d2.programModule().programTrackedEntityAttributes()
.byProgram().eq(programUid)
.byDisplayInList().isTrue()
.orderBySortOrder(RepositoryScope.OrderByDirection.ASC)
.blockingGet();
for (ProgramTrackedEntityAttribute programAttribute : programTrackedEntityAttributes) {
attributeUids.add(programAttribute.trackedEntityAttribute().uid());
}
attributesUidsCache.put(programUid, attributeUids);
}

return attributesUidsCache.get(programUid);
}

private List<String> getTETypeAttributeUids(String teTypeUid){
if(!trackedEntityTypeAttributesUidsCache.containsKey(teTypeUid)){
List<String> attributeUids = new ArrayList<>();
List<TrackedEntityTypeAttribute> typeAttributes = d2.trackedEntityModule().trackedEntityTypeAttributes()
.byTrackedEntityTypeUid().eq(teTypeUid)
.byDisplayInList().isTrue()
.blockingGet();

for (TrackedEntityTypeAttribute typeAttribute : typeAttributes) {
attributeUids.add(typeAttribute.trackedEntityAttribute().uid());
}
}
return trackedEntityTypeAttributesUidsCache.get(teTypeUid);
}

private int getTeiDefaultRes(TrackedEntityInstance tei) {
TrackedEntityType teiType = d2.trackedEntityModule().trackedEntityTypes().uid(tei.trackedEntityType()).blockingGet();
return resources.getObjectStyleDrawableResource(teiType.style().icon(), R.drawable.photo_temp_gray);
Expand All @@ -501,40 +536,23 @@ private int getTeiDefaultRes(TrackedEntityInstance tei) {
private List<TrackedEntityAttributeValue> getTrackedEntityAttributesForRelationship(TrackedEntityInstance tei, Program selectedProgram) {

List<TrackedEntityAttributeValue> values;
List<String> attributeUids = new ArrayList<>();
List<ProgramTrackedEntityAttribute> programTrackedEntityAttributes = d2.programModule().programTrackedEntityAttributes()
.byProgram().eq(selectedProgram.uid())
.byDisplayInList().isTrue()
.orderBySortOrder(RepositoryScope.OrderByDirection.ASC)
.blockingGet();
for (ProgramTrackedEntityAttribute programAttribute : programTrackedEntityAttributes) {
attributeUids.add(programAttribute.trackedEntityAttribute().uid());
}
values = d2.trackedEntityModule().trackedEntityAttributeValues()
.byTrackedEntityInstance().eq(tei.uid())
.byTrackedEntityAttribute().in(attributeUids).blockingGet();
.byTrackedEntityAttribute().in(getProgramAttributeUids(selectedProgram.uid())).blockingGet();

if (values.isEmpty()) {
attributeUids.clear();
List<TrackedEntityTypeAttribute> typeAttributes = d2.trackedEntityModule().trackedEntityTypeAttributes()
.byTrackedEntityTypeUid().eq(tei.trackedEntityType())
.byDisplayInList().isTrue()
.blockingGet();

for (TrackedEntityTypeAttribute typeAttribute : typeAttributes) {
attributeUids.add(typeAttribute.trackedEntityAttribute().uid());
}
values = d2.trackedEntityModule().trackedEntityAttributeValues()
.byTrackedEntityInstance().eq(tei.uid())
.byTrackedEntityAttribute().in(attributeUids).blockingGet();
.byTrackedEntityAttribute().in(getTETypeAttributeUids(tei.trackedEntityType())).blockingGet();
}

return values;
}

@Override
public String getProgramColor(@NonNull String programUid) {
Program program = d2.programModule().programs().byUid().eq(programUid).one().blockingGet();
Program program = getProgram(programUid);
if(program == null) return "";
return program.style() != null ?
program.style().color() != null ?
program.style().color() :
Expand Down Expand Up @@ -607,40 +625,51 @@ public List<EventViewModel> getEventsForMap(List<SearchTeiModel> teis) {
.byDeleted().isFalse()
.blockingGet();

for (Event event : events) {
ProgramStage stage = d2.programModule().programStages()
.uid(event.programStage())
.blockingGet();
HashMap<String,ProgramStage> cacheStages = new HashMap<>();

OrganisationUnit organisationUnit = d2.organisationUnitModule()
.organisationUnits()
.uid(event.organisationUnit())
.blockingGet();
for (Event event : events) {
if(!cacheStages.containsKey(event.programStage())){
ProgramStage stage = d2.programModule().programStages()
.uid(event.programStage())
.blockingGet();
cacheStages.put(event.programStage(), stage);
}

eventViewModels.add(
new EventViewModel(
EventViewModelType.EVENT,
stage,
cacheStages.get(event.programStage()),
event,
0,
null,
true,
true,
organisationUnit.displayName(),
orgUnitName(event.organisationUnit()),
null,
null,
false,
false,
false,
false,
periodUtils.getPeriodUIString(stage.periodType(), event.eventDate() != null ? event.eventDate() : event.dueDate(), Locale.getDefault()),
periodUtils.getPeriodUIString(cacheStages.get(event.programStage()).periodType(), event.eventDate() != null ? event.eventDate() : event.dueDate(), Locale.getDefault()),
null
));
}

return eventViewModels;
}

private String orgUnitName(String orgUnitUid){
if(!orgUnitNameCache.containsKey(orgUnitUid)){
OrganisationUnit organisationUnit = d2.organisationUnitModule()
.organisationUnits()
.uid(orgUnitUid)
.blockingGet();
orgUnitNameCache.put(orgUnitUid, organisationUnit.displayName());
}
return orgUnitNameCache.get(orgUnitUid);
}

@Override
public SearchTeiModel getTrackedEntityInfo(String teiUid, Program selectedProgram, SortingItem sortingItem) {
return transform(
Expand Down Expand Up @@ -727,20 +756,21 @@ public SearchTeiModel transform(TrackedEntitySearchItem searchItem, @Nullable Pr
SearchTeiModel searchTei = new SearchTeiModel();
if (dbTei != null && dbTei.aggregatedSyncState() != State.RELATIONSHIP) {
searchTei.setTei(dbTei);
if (selectedProgram != null && d2.enrollmentModule().enrollments().byTrackedEntityInstance().eq(dbTei.uid()).byProgram().eq(selectedProgram.uid()).one().blockingExists()) {
List<Enrollment> possibleEnrollments = d2.enrollmentModule().enrollments()
.byTrackedEntityInstance().eq(dbTei.uid())
.byProgram().eq(selectedProgram.uid())
.orderByEnrollmentDate(RepositoryScope.OrderByDirection.DESC)
.blockingGet();
for (Enrollment enrollment : possibleEnrollments) {
List<Enrollment> enrollmentsInProgram = d2.enrollmentModule().enrollments()
.byTrackedEntityInstance().eq(dbTei.uid())
.byProgram().eq(selectedProgram.uid())
.orderByEnrollmentDate(RepositoryScope.OrderByDirection.DESC)
.blockingGet();

if (!enrollmentsInProgram.isEmpty()) {
for (Enrollment enrollment : enrollmentsInProgram) {
if (enrollment.status() == EnrollmentStatus.ACTIVE) {
searchTei.setCurrentEnrollment(enrollment);
break;
}
}
if (searchTei.getSelectedEnrollment() == null) {
searchTei.setCurrentEnrollment(possibleEnrollments.get(0));
searchTei.setCurrentEnrollment(enrollmentsInProgram.get(0));
}
}

Expand All @@ -749,7 +779,7 @@ public SearchTeiModel transform(TrackedEntitySearchItem searchItem, @Nullable Pr
if (offlineOnly)
searchTei.setOnline(!offlineOnly);

if (dbTei.deleted() != null && dbTei.deleted()) {
if (Boolean.TRUE.equals(dbTei.deleted())) {
searchTei.setOnline(true);
}

Expand All @@ -760,14 +790,14 @@ public SearchTeiModel transform(TrackedEntitySearchItem searchItem, @Nullable Pr
setRelationshipsInfo(searchTei, selectedProgram);
}
if (searchTei.getSelectedEnrollment() != null) {
searchTei.setEnrolledOrgUnit(d2.organisationUnitModule().organisationUnits().uid(searchTei.getSelectedEnrollment().organisationUnit()).blockingGet().name());
searchTei.setEnrolledOrgUnit(orgUnitName(searchTei.getSelectedEnrollment().organisationUnit()));
} else {
searchTei.setEnrolledOrgUnit(d2.organisationUnitModule().organisationUnits().uid(searchTei.getTei().organisationUnit()).blockingGet().name());
searchTei.setEnrolledOrgUnit(orgUnitName(searchTei.getTei().organisationUnit()));
}
searchTei.setProfilePicture(profilePicturePath(dbTei, selectedProgram));
} else {
searchTei.setTei(teiFromItem);
searchTei.setEnrolledOrgUnit(d2.organisationUnitModule().organisationUnits().uid(searchTei.getTei().organisationUnit()).blockingGet().name());
searchTei.setEnrolledOrgUnit(orgUnitName(searchTei.getTei().organisationUnit()));

for (TrackedEntitySearchItemAttribute attribute : searchItem.getAttributeValues()) {
if (attribute.getDisplayInList()) {
Expand Down Expand Up @@ -882,9 +912,13 @@ public boolean eventsHaveCoordinates(String programUid) {
@Nullable
@Override
public Program getProgram(@Nullable String programUid) {
if (programUid == null)
return null;
return d2.programModule().programs().uid(programUid).blockingGet();
if (programUid == null) return null;

if (!programCache.containsKey(programUid)) {
Program program = d2.programModule().programs().uid(programUid).blockingGet();
programCache.put(program.uid(), program);
}
return programCache.get(programUid);
}

@Override
Expand Down Expand Up @@ -929,8 +963,8 @@ public boolean canCreateInProgramWithoutSearch() {
}

private boolean displayOrgUnit() {
return d2.organisationUnitModule().organisationUnits()
.byProgramUids(Collections.singletonList(currentProgram))
.blockingGet().size() > 1;
return d2.organisationUnitModule().organisationUnits()
.byProgramUids(Collections.singletonList(currentProgram))
.blockingGet().size() > 1;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -111,11 +111,6 @@ public void resetEnrollments() {
this.enrollmentsInfo.clear();
}

public List<Trio<String, String, String>> getEnrollmentInfo() {
Collections.sort(enrollmentsInfo, (enrollment1, enrollment2) -> enrollment1.val0().compareToIgnoreCase(enrollment2.val0()));
return enrollmentsInfo;
}

public void setAttributeValues(LinkedHashMap<String, TrackedEntityAttributeValue> attributeValues) {
this.attributeValues = attributeValues;
}
Expand Down

0 comments on commit cc20ed7

Please sign in to comment.