Work on perf
This commit is contained in:
parent
1039bbec97
commit
f6acb5633b
|
@ -977,15 +977,19 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
|
|||
|
||||
@Override
|
||||
public Set<Long> searchForIdsWithAndOr(SearchParameterMap theParams) {
|
||||
theParams.setPersistResults(false);
|
||||
|
||||
SearchBuilder builder = newSearchBuilder();
|
||||
builder.setType(getResourceType(), getResourceName());
|
||||
List<Long> result = builder.loadSearchPage(theParams, 0, 100);
|
||||
|
||||
|
||||
// FIXME: fail if too many results
|
||||
|
||||
HashSet<Long> retVal = new HashSet<Long>(result);
|
||||
HashSet<Long> retVal = new HashSet<Long>();
|
||||
|
||||
Iterator<Long> iter = builder.createQuery(theParams);
|
||||
while (iter.hasNext()) {
|
||||
retVal.add(iter.next());
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
|
|
|
@ -1559,11 +1559,12 @@ public class SearchBuilder {
|
|||
/*
|
||||
* Now perform the search
|
||||
*/
|
||||
TypedQuery<Long> query = myEntityManager.createQuery(outerQuery);
|
||||
final Iterator<Long> results = query.getResultList().iterator();
|
||||
final Set<Long> pidSet = new HashSet<Long>();
|
||||
final TypedQuery<Long> query = myEntityManager.createQuery(outerQuery);
|
||||
|
||||
return new Iterator<Long>() {
|
||||
|
||||
private final Set<Long> myPidSet = new HashSet<Long>();
|
||||
private Iterator<Long> myResultsIterator;
|
||||
private Long myNext;
|
||||
|
||||
@Override
|
||||
|
@ -1578,10 +1579,13 @@ public class SearchBuilder {
|
|||
}
|
||||
|
||||
private void fetchNext() {
|
||||
if (myResultsIterator == null) {
|
||||
myResultsIterator = query.getResultList().iterator();
|
||||
}
|
||||
if (myNext == null) {
|
||||
while (results.hasNext()) {
|
||||
Long next = results.next();
|
||||
if (next != null && pidSet.add(next)) {
|
||||
while (myResultsIterator.hasNext()) {
|
||||
Long next = myResultsIterator.next();
|
||||
if (next != null && myPidSet.add(next)) {
|
||||
myNext = next;
|
||||
break;
|
||||
}
|
||||
|
@ -1604,45 +1608,42 @@ public class SearchBuilder {
|
|||
private static Long NO_MORE = Long.valueOf(-1);
|
||||
|
||||
public IBundleProvider search(final SearchParameterMap theParams) {
|
||||
myParams = theParams;
|
||||
StopWatch w = new StopWatch();
|
||||
|
||||
if (theParams.isLoadSynchronous()) {
|
||||
|
||||
}
|
||||
|
||||
mySearchEntity = new Search();
|
||||
mySearchEntity.setUuid(UUID.randomUUID().toString());
|
||||
mySearchEntity.setCreated(new Date());
|
||||
mySearchEntity.setTotalCount(-1);
|
||||
mySearchEntity.setPreferredPageSize(myParams.getCount());
|
||||
mySearchEntity.setSearchType(myParams.getEverythingMode() != null ? SearchTypeEnum.EVERYTHING : SearchTypeEnum.SEARCH);
|
||||
mySearchEntity.setLastUpdated(myParams.getLastUpdated());
|
||||
mySearchEntity.setResourceType(myResourceName);
|
||||
|
||||
for (Include next : myParams.getIncludes()) {
|
||||
mySearchEntity.getIncludes().add(new SearchInclude(mySearchEntity, next.getValue(), false, next.isRecurse()));
|
||||
}
|
||||
for (Include next : myParams.getRevIncludes()) {
|
||||
mySearchEntity.getIncludes().add(new SearchInclude(mySearchEntity, next.getValue(), true, next.isRecurse()));
|
||||
}
|
||||
|
||||
List<Long> firstPage = loadSearchPage(theParams, 0, 999);
|
||||
mySearchEntity.setTotalCount(firstPage.size());
|
||||
|
||||
myEntityManager.persist(mySearchEntity);
|
||||
for (SearchInclude next : mySearchEntity.getIncludes()) {
|
||||
myEntityManager.persist(next);
|
||||
}
|
||||
|
||||
IBundleProvider retVal = doReturnProvider();
|
||||
|
||||
ourLog.info("Search initial phase completed in {}ms", w);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
public List<Long> loadSearchPage(SearchParameterMap theParams, int theFromIndex, int theToIndex) {
|
||||
|
||||
// myParams = theParams;
|
||||
// StopWatch w = new StopWatch();
|
||||
//
|
||||
// if (theParams.isLoadSynchronous()) {
|
||||
//
|
||||
// }
|
||||
//
|
||||
// mySearchEntity = new Search();
|
||||
// mySearchEntity.setUuid(UUID.randomUUID().toString());
|
||||
// mySearchEntity.setCreated(new Date());
|
||||
// mySearchEntity.setTotalCount(-1);
|
||||
// mySearchEntity.setPreferredPageSize(myParams.getCount());
|
||||
// mySearchEntity.setSearchType(myParams.getEverythingMode() != null ? SearchTypeEnum.EVERYTHING : SearchTypeEnum.SEARCH);
|
||||
// mySearchEntity.setLastUpdated(myParams.getLastUpdated());
|
||||
// mySearchEntity.setResourceType(myResourceName);
|
||||
//
|
||||
// for (Include next : myParams.getIncludes()) {
|
||||
// mySearchEntity.getIncludes().add(new SearchInclude(mySearchEntity, next.getValue(), false, next.isRecurse()));
|
||||
// }
|
||||
// for (Include next : myParams.getRevIncludes()) {
|
||||
// mySearchEntity.getIncludes().add(new SearchInclude(mySearchEntity, next.getValue(), true, next.isRecurse()));
|
||||
// }
|
||||
//
|
||||
// List<Long> firstPage = loadSearchPage(theParams, 0, 999);
|
||||
// mySearchEntity.setTotalCount(firstPage.size());
|
||||
//
|
||||
// myEntityManager.persist(mySearchEntity);
|
||||
// for (SearchInclude next : mySearchEntity.getIncludes()) {
|
||||
// myEntityManager.persist(next);
|
||||
// }
|
||||
//
|
||||
// IBundleProvider retVal = doReturnProvider();
|
||||
//
|
||||
// ourLog.info("Search initial phase completed in {}ms", w);
|
||||
// return retVal;
|
||||
return null;
|
||||
}
|
||||
|
||||
// public IBundleProvider loadPage(SearchParameterMap theParams, int theFromIndex, int theToIndex) {
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
package ca.uhn.fhir.jpa.search;
|
||||
|
||||
public class ISearchCoordinatorSvc {
|
||||
|
||||
}
|
|
@ -125,15 +125,15 @@ public final class PersistedJpaBundleProvider implements IBundleProvider {
|
|||
// List<Long> pidsSubList = sb.loadSearchPage(parameterMap, theFromIndex, theToIndex);());
|
||||
List<Long> pidsSubList = null;
|
||||
|
||||
Set<Long> revIncludedPids = new HashSet<Long>();
|
||||
Set<Long> includedPids = new HashSet<Long>();
|
||||
if (mySearchEntity.getSearchType() == SearchTypeEnum.SEARCH) {
|
||||
revIncludedPids.addAll(SearchBuilder.loadReverseIncludes(myDao, myContext, myEntityManager, pidsSubList, mySearchEntity.toRevIncludesList(), true, mySearchEntity.getLastUpdated()));
|
||||
includedPids.addAll(SearchBuilder.loadReverseIncludes(myDao, myContext, myEntityManager, pidsSubList, mySearchEntity.toRevIncludesList(), true, mySearchEntity.getLastUpdated()));
|
||||
}
|
||||
revIncludedPids.addAll(SearchBuilder.loadReverseIncludes(myDao, myContext, myEntityManager, pidsSubList, mySearchEntity.toIncludesList(), false, mySearchEntity.getLastUpdated()));
|
||||
includedPids.addAll(SearchBuilder.loadReverseIncludes(myDao, myContext, myEntityManager, pidsSubList, mySearchEntity.toIncludesList(), false, mySearchEntity.getLastUpdated()));
|
||||
|
||||
// Execute the query and make sure we return distinct results
|
||||
List<IBaseResource> resources = new ArrayList<IBaseResource>();
|
||||
SearchBuilder.loadResourcesByPid(pidsSubList, resources, revIncludedPids, false, myEntityManager, myContext, myDao);
|
||||
SearchBuilder.loadResourcesByPid(pidsSubList, resources, includedPids, false, myEntityManager, myContext, myDao);
|
||||
|
||||
return resources;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,83 @@
|
|||
package ca.uhn.fhir.jpa.search;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
|
||||
import org.springframework.scheduling.concurrent.CustomizableThreadFactory;
|
||||
import org.springframework.transaction.PlatformTransactionManager;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.jpa.dao.IDao;
|
||||
import ca.uhn.fhir.jpa.dao.IFulltextSearchSvc;
|
||||
import ca.uhn.fhir.jpa.dao.SearchBuilder;
|
||||
import ca.uhn.fhir.jpa.dao.SearchParameterMap;
|
||||
import ca.uhn.fhir.jpa.dao.data.IResourceIndexedSearchParamUriDao;
|
||||
import ca.uhn.fhir.jpa.dao.data.ISearchResultDao;
|
||||
import ca.uhn.fhir.jpa.util.StopWatch;
|
||||
import ca.uhn.fhir.rest.server.IBundleProvider;
|
||||
|
||||
public class SearchCoordinatorSvcImpl {
|
||||
|
||||
|
||||
public SearchCoordinatorSvcImpl() {
|
||||
CustomizableThreadFactory threadFactory = new CustomizableThreadFactory("search_coord_");
|
||||
myExecutor = Executors.newCachedThreadPool(threadFactory);
|
||||
}
|
||||
|
||||
public IBundleProvider registerSearch(IDao theCallingDao, SearchParameterMap theParams) {
|
||||
StopWatch w = new StopWatch();
|
||||
|
||||
if (theParams.isLoadSynchronous()) {
|
||||
SearchBuilder sb = theCallingDao.newSearchBuilder();
|
||||
Iterator<Long> resultIter = sb.createQuery(theParams);
|
||||
|
||||
// Load the results synchronously
|
||||
List<Long> pids = new ArrayList<Long>();
|
||||
while (resultIter.hasNext()) {
|
||||
pids.add(resultIter.next());
|
||||
if (theParams.getLoadSynchronousUpTo() != null && pids.size() >= theParams.getLoadSynchronousUpTo()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
resources = sb.loadResourcesByPid(pids, theResourceListToPopulate, theRevIncludedPids, theForHistoryOperation, entityManager, context, theDao);
|
||||
}
|
||||
|
||||
mySearchEntity = new Search();
|
||||
mySearchEntity.setUuid(UUID.randomUUID().toString());
|
||||
mySearchEntity.setCreated(new Date());
|
||||
mySearchEntity.setTotalCount(-1);
|
||||
mySearchEntity.setPreferredPageSize(myParams.getCount());
|
||||
mySearchEntity.setSearchType(myParams.getEverythingMode() != null ? SearchTypeEnum.EVERYTHING : SearchTypeEnum.SEARCH);
|
||||
mySearchEntity.setLastUpdated(myParams.getLastUpdated());
|
||||
mySearchEntity.setResourceType(myResourceName);
|
||||
|
||||
for (Include next : myParams.getIncludes()) {
|
||||
mySearchEntity.getIncludes().add(new SearchInclude(mySearchEntity, next.getValue(), false, next.isRecurse()));
|
||||
}
|
||||
for (Include next : myParams.getRevIncludes()) {
|
||||
mySearchEntity.getIncludes().add(new SearchInclude(mySearchEntity, next.getValue(), true, next.isRecurse()));
|
||||
}
|
||||
|
||||
List<Long> firstPage = loadSearchPage(theParams, 0, 999);
|
||||
mySearchEntity.setTotalCount(firstPage.size());
|
||||
|
||||
myEntityManager.persist(mySearchEntity);
|
||||
for (SearchInclude next : mySearchEntity.getIncludes()) {
|
||||
myEntityManager.persist(next);
|
||||
}
|
||||
|
||||
IBundleProvider retVal = doReturnProvider();
|
||||
|
||||
ourLog.info("Search initial phase completed in {}ms", w);
|
||||
return retVal;
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue