use of org.orcid.persistence.jpa.entities.WorkBaseEntity in project ORCID-Source by ORCID.
the class WorkEntityCacheManagerImpl method retrieveWorkList.
/**
* Fetches a list of minimised works - does this by checking cache and then
* fetching all misses in one go from the DB.
*
* @param workIdsWithLastModified
* @return
*/
@Override
public <T extends WorkBaseEntity> List<T> retrieveWorkList(Map<Long, Date> workIdsWithLastModified, Cache workCache, LockerObjectsManager lockerObjectsManager, Function<List<Long>, List<T>> workRetriever) {
WorkBaseEntity[] returnArray = new WorkBaseEntity[workIdsWithLastModified.size()];
List<Long> fetchList = new ArrayList<Long>();
Map<Long, Integer> fetchListIndexOrder = new LinkedHashMap<Long, Integer>();
int index = 0;
for (Long workId : workIdsWithLastModified.keySet()) {
// get works from the cache if we can
Object key = new WorkCacheKey(workId, releaseName);
WorkBaseEntity cachedWork = toWorkBaseEntity(workCache.get(key));
if (cachedWork == null || cachedWork.getLastModified().getTime() < workIdsWithLastModified.get(workId).getTime()) {
fetchListIndexOrder.put(workId, index);
fetchList.add(workId);
} else {
returnArray[index] = cachedWork;
}
index++;
}
// now fetch all the others that are *not* in the cache
if (fetchList.size() > 0) {
List<? extends WorkBaseEntity> refreshedWorks = workRetriever.apply(fetchList);
for (WorkBaseEntity mWorkRefreshedFromDB : refreshedWorks) {
Object key = new WorkCacheKey(mWorkRefreshedFromDB.getId(), releaseName);
try {
synchronized (lockerObjectsManager.obtainLock(Long.toString(mWorkRefreshedFromDB.getId()))) {
// check cache again here to prevent race condition
// since something could have updated while we were
// fetching from DB
// (or can we skip because new last modified is always
// going to be after profile last modified as provided)
WorkBaseEntity cachedWork = toWorkBaseEntity(workCache.get(key));
int returnListIndex = fetchListIndexOrder.get(mWorkRefreshedFromDB.getId());
if (cachedWork == null || cachedWork.getLastModified().getTime() < workIdsWithLastModified.get(mWorkRefreshedFromDB.getId()).getTime()) {
workCache.put(new Element(key, mWorkRefreshedFromDB));
returnArray[returnListIndex] = mWorkRefreshedFromDB;
} else {
returnArray[returnListIndex] = cachedWork;
}
}
} finally {
lockerObjectsManager.releaseLock(Long.toString(mWorkRefreshedFromDB.getId()));
}
}
}
@SuppressWarnings("unchecked") List<T> results = (List<T>) Arrays.asList(returnArray);
return results;
}
Aggregations