180 lines
5.1 KiB
Java
180 lines
5.1 KiB
Java
package eu.dnetlib.enabling.resultset.push;
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.List;
|
|
|
|
import javax.annotation.Resource;
|
|
|
|
import org.apache.commons.logging.Log;
|
|
import org.apache.commons.logging.LogFactory;
|
|
import org.springframework.beans.factory.annotation.Required;
|
|
|
|
import eu.dnetlib.enabling.resultset.push.ResultSetDescriptor.Range;
|
|
import eu.dnetlib.miscutils.cache.Cache;
|
|
import eu.dnetlib.miscutils.factory.Factory;
|
|
|
|
/**
|
|
* implement a resultset dao.
|
|
*
|
|
* @author marko
|
|
*
|
|
*/
|
|
public class CacheTransientResultSetDaoImpl implements TransientPushResultSetDao {
|
|
|
|
/**
|
|
* logger.
|
|
*/
|
|
private static final Log log = LogFactory.getLog(CacheTransientResultSetDaoImpl.class); // NOPMD by marko on 11/24/08 5:02 PM
|
|
|
|
/**
|
|
* range cache. Keys are "rsid-rangenumber".
|
|
*/
|
|
private Cache<String, List<String>> cache;
|
|
|
|
/**
|
|
* resultsets
|
|
*/
|
|
private Cache<String, ResultSetDescriptor> resultSetCache;
|
|
|
|
/**
|
|
* resultset descriptor factory.
|
|
*/
|
|
@Resource
|
|
private Factory<ResultSetDescriptor> resultSetDescriptorFactory;
|
|
|
|
/**
|
|
* {@inheritDoc}
|
|
*
|
|
* @see eu.dnetlib.enabling.resultset.push.TransientPushResultSetDao#getSize(java.lang.String)
|
|
*/
|
|
@Override
|
|
public int getSize(final String key) {
|
|
final ResultSetDescriptor desc = resultSetCache.get(key);
|
|
if (desc == null)
|
|
return 0;
|
|
return (desc.getRanges() - 1) * desc.getRangeLength() + cache.get(key + "-" + desc.getLastRange()).size();
|
|
}
|
|
|
|
/**
|
|
* {@inheritDoc}
|
|
*
|
|
* @see eu.dnetlib.enabling.resultset.push.TransientPushResultSetDao#addElements(java.lang.String, java.util.List)
|
|
*/
|
|
@Override
|
|
public void addElements(final String key, final List<String> elements) {
|
|
// TODO: huuuuu, chaos, fix this please!
|
|
synchronized (cache) {
|
|
|
|
ResultSetDescriptor desc = resultSetCache.get(key);
|
|
|
|
log.debug("got desc: " + desc);
|
|
if (desc == null) {
|
|
desc = resultSetDescriptorFactory.newInstance();
|
|
resultSetCache.put(key, desc);
|
|
}
|
|
log.debug("desc now is desc: " + desc);
|
|
|
|
if (elements.size() > desc.getRangeLength())
|
|
throw new IllegalArgumentException("The current implementation of the push resultset doesn't accept pages longer than "
|
|
+ desc.getRangeLength() + ", got: " + elements.size());
|
|
|
|
|
|
int lastRangeIndex = desc.getLastRange();
|
|
|
|
if (lastRangeIndex < 0)
|
|
lastRangeIndex = 0;
|
|
|
|
log.debug("last range: " + lastRangeIndex);
|
|
|
|
List<String> lastRange = cache.get(key + "-" + lastRangeIndex);
|
|
log.debug("stored last range: " + lastRange);
|
|
|
|
if (lastRange == null) {
|
|
lastRange = new ArrayList<String>();
|
|
desc.setRanges(desc.getRanges() + 1);
|
|
}
|
|
|
|
log.debug("last range is: " + lastRange);
|
|
|
|
final int free = desc.getRangeLength() - lastRange.size();
|
|
log.debug("free: " + free);
|
|
log.debug("desc range length: " + desc.getRangeLength());
|
|
log.debug("last range size: " + lastRange.size());
|
|
|
|
int toElements = free;
|
|
if (toElements > elements.size()) {
|
|
toElements = elements.size();
|
|
} else {
|
|
|
|
final List<String> nextRange = new ArrayList<String>(elements.subList(free, elements.size()));
|
|
log.debug("next range: " + nextRange);
|
|
|
|
cache.put(key + "-" + (lastRangeIndex + 1), nextRange);
|
|
log.debug("next range stored at: " + key + "-" + (lastRangeIndex + 1));
|
|
desc.setRanges(desc.getRanges() + 1);
|
|
}
|
|
lastRange.addAll(elements.subList(0, toElements));
|
|
|
|
log.debug("LAST RANGE SIZE: " + lastRange.size() + " range index " + lastRangeIndex);
|
|
|
|
log.debug("after add: " + lastRange);
|
|
|
|
cache.put(key + "-" + lastRangeIndex, lastRange);
|
|
log.debug("range stored at: " + key + "-" + lastRangeIndex);
|
|
|
|
resultSetCache.put(key, desc);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* {@inheritDoc}
|
|
*
|
|
* @see eu.dnetlib.enabling.resultset.push.TransientPushResultSetDao#getElements(java.lang.String, int, int)
|
|
*/
|
|
@Override
|
|
public List<String> getElements(final String key, final int fromPosition, final int toPosition) {
|
|
ResultSetDescriptor desc = resultSetCache.get(key);
|
|
log.debug("got desc: " + desc);
|
|
|
|
if (desc == null)
|
|
desc = resultSetDescriptorFactory.newInstance();
|
|
|
|
final List<String> res = new ArrayList<String>();
|
|
|
|
log.debug("ranges containing " + fromPosition + " to " + toPosition);
|
|
for (final Range range : desc.getRangesContaining(fromPosition, toPosition)) {
|
|
log.debug("reading range " + key + "-" + range.getRange() + " begin: " + range.getBegin() + " end: " + range.getEnd());
|
|
res.addAll(cache.get(key + "-" + range.getRange()).subList(range.getBegin(), range.getEnd()));
|
|
}
|
|
|
|
return res;
|
|
}
|
|
|
|
public Cache<String, List<String>> getCache() {
|
|
return cache;
|
|
}
|
|
|
|
@Required
|
|
public void setCache(final Cache<String, List<String>> cache) {
|
|
this.cache = cache;
|
|
}
|
|
|
|
public Cache<String, ResultSetDescriptor> getResultSetCache() {
|
|
return resultSetCache;
|
|
}
|
|
|
|
@Required
|
|
public void setResultSetCache(final Cache<String, ResultSetDescriptor> resultSetCache) {
|
|
this.resultSetCache = resultSetCache;
|
|
}
|
|
|
|
public Factory<ResultSetDescriptor> getResultSetDescriptorFactory() {
|
|
return resultSetDescriptorFactory;
|
|
}
|
|
|
|
public void setResultSetDescriptorFactory(final Factory<ResultSetDescriptor> resultSetDescriptorFactory) {
|
|
this.resultSetDescriptorFactory = resultSetDescriptorFactory;
|
|
}
|
|
|
|
}
|