During parent uid loading seek to next parent type when child type is encountered.

Relates to #3028
This commit is contained in:
Martijn van Groningen 2013-05-14 16:22:05 +02:00
parent 6d5805c901
commit 15fcb17a81
1 changed files with 21 additions and 4 deletions

View File

@ -27,6 +27,7 @@ import org.elasticsearch.common.bytes.HashedBytesArray;
import org.elasticsearch.common.collect.MapBuilder;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.text.UTF8SortedAsUnicodeComparator;
import org.elasticsearch.common.trove.ExtTObjectIntHasMap;
import org.elasticsearch.common.util.concurrent.ConcurrentCollections;
import org.elasticsearch.index.AbstractIndexComponent;
@ -117,7 +118,7 @@ public class SimpleIdCache extends AbstractIndexComponent implements IdCache, Se
Map<Object, IndexReader> cacheToReader = new HashMap<Object, IndexReader>();
// We don't want to load uid of child documents, this allows us to not load uids of child types.
Set<HashedBytesArray> parentTypes = new HashSet<HashedBytesArray>();
TreeSet<HashedBytesArray> parentTypes = new TreeSet<HashedBytesArray>(UTF8SortedAsUnicodeComparator.utf8SortedAsUnicodeSortOrder);
for (String type : indexService.mapperService().types()) {
ParentFieldMapper parentFieldMapper = indexService.mapperService().documentMapper(type).parentFieldMapper();
if (parentFieldMapper != null) {
@ -145,11 +146,27 @@ public class SimpleIdCache extends AbstractIndexComponent implements IdCache, Se
if (terms != null) {
TermsEnum termsEnum = terms.iterator(null);
DocsEnum docsEnum = null;
for (BytesRef term = termsEnum.next(); term != null; term = termsEnum.next()) {
uid: for (BytesRef term = termsEnum.next(); term != null; term = termsEnum.next()) {
HashedBytesArray[] typeAndId = Uid.splitUidIntoTypeAndId(term);
// TODO: seek!
if (!parentTypes.contains(typeAndId[0])) {
continue;
do {
HashedBytesArray nextParent = parentTypes.ceiling(typeAndId[0]);
if (nextParent == null) {
break uid;
}
TermsEnum.SeekStatus status = termsEnum.seekCeil(nextParent.toBytesRef(), false);
if (status == TermsEnum.SeekStatus.END) {
break uid;
} else if (status == TermsEnum.SeekStatus.NOT_FOUND) {
term = termsEnum.term();
typeAndId = Uid.splitUidIntoTypeAndId(term);
} else if (status == TermsEnum.SeekStatus.FOUND) {
assert false : "Seek status should never be FOUND, because we seek only the type part";
term = termsEnum.term();
typeAndId = Uid.splitUidIntoTypeAndId(term);
}
} while (!parentTypes.contains(typeAndId[0]));
}
String type = typeAndId[0].toUtf8();