package com.constellio.model.services.search.cache;
import java.util.AbstractList;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import com.constellio.model.entities.records.Record;
import com.constellio.model.services.factories.ModelLayerFactory;
import com.constellio.model.services.records.RecordServices;
import com.constellio.model.services.records.cache.RecordsCaches;
import com.constellio.model.services.search.SPEQueryResponse;
import com.constellio.model.services.search.SearchServices;
import com.constellio.model.services.search.query.logical.LogicalSearchQuery;
public class LazyRecordList extends AbstractList<Record> {
private int batchSize;
private SerializableSearchCache cache;
private RecordsCaches recordsCaches;
private LogicalSearchQuery query;
private RecordServices recordServices;
private SearchServices searchServices;
private boolean serializeRecords;
LazyRecordList(int batchSize, SerializableSearchCache cache, ModelLayerFactory modelLayerFactory,
LogicalSearchQuery query, boolean serializeRecords) {
this.batchSize = batchSize;
this.recordsCaches = modelLayerFactory.getRecordsCaches();
this.cache = cache;
this.recordServices = modelLayerFactory.newRecordServices();
this.searchServices = modelLayerFactory.newSearchServices();
this.query = new LogicalSearchQuery(query);
this.serializeRecords = serializeRecords;
}
@Override
public Record get(int index) {
String recordId = cache.getCachedId(index);
if (recordId == null) {
return fetchIndex(index);
} else {
if (serializeRecords) {
return cache.getCachedRecord(index);
} else {
return recordServices.getDocumentById(recordId);
}
}
}
private Record fetchIndex(int index) {
SPEQueryResponse speQueryResponse = searchServices.query(query.setNumberOfRows(batchSize).setStartRow(index));
cache.setSize((int) speQueryResponse.getNumFound());
List<Record> recordsToInsert = new ArrayList<>();
Record returnedRecord = null;
for (int i = 0; i < batchSize; i++) {
if (i < speQueryResponse.getRecords().size()) {
Record record = speQueryResponse.getRecords().get(i);
cache.setRecordId(index + i, record.getId());
if (serializeRecords) {
cache.setRecord(index + i, record);
}
recordsToInsert.add(record);
if (returnedRecord == null) {
returnedRecord = record;
}
Map<String, List<String>> recordHighlighting = speQueryResponse.getHighlighting(record.getId());
cache.setRecordHighLighting(record.getId(), recordHighlighting);
}
}
if (!recordsToInsert.isEmpty()) {
recordsCaches.insert(recordsToInsert.get(0).getCollection(), recordsToInsert);
}
return returnedRecord;
}
@Override
public int size() {
int size = cache.getSize();
if (size == -1) {
fetchIndex(0);
size = cache.getSize();
}
return size;
}
}