org.elasticsearch.index.engine.RewriteCachingDirectoryReader Maven / Gradle / Ivy
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
package org.elasticsearch.index.engine;
import org.apache.lucene.index.BinaryDocValues;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.FieldInfo;
import org.apache.lucene.index.FieldInfos;
import org.apache.lucene.index.Fields;
import org.apache.lucene.index.IndexCommit;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.LeafMetaData;
import org.apache.lucene.index.LeafReader;
import org.apache.lucene.index.LeafReaderContext;
import org.apache.lucene.index.NumericDocValues;
import org.apache.lucene.index.PointValues;
import org.apache.lucene.index.SortedDocValues;
import org.apache.lucene.index.SortedNumericDocValues;
import org.apache.lucene.index.SortedSetDocValues;
import org.apache.lucene.index.StoredFieldVisitor;
import org.apache.lucene.index.Terms;
import org.apache.lucene.store.Directory;
import org.apache.lucene.util.Bits;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* This special DirectoryReader is used to handle can_match requests against frozen indices.
* It' caches all relevant point value data for every point value field ie. min/max packed values etc.
* to hold enough information to rewrite a date range query and make a decisions if an index can match or not.
* This allows frozen indices to be searched with wildcards in a very efficient way without opening a reader on them.
*/
final class RewriteCachingDirectoryReader extends DirectoryReader {
RewriteCachingDirectoryReader(Directory directory, List segmentReaders) throws
IOException {
super(directory, wrap(segmentReaders));
}
private static LeafReader[] wrap(List readers) throws IOException {
LeafReader[] wrapped = new LeafReader[readers.size()];
int i = 0;
for (LeafReaderContext ctx : readers) {
LeafReader wrap = new RewriteCachingLeafReader(ctx.reader());
wrapped[i++] = wrap;
}
return wrapped;
}
@Override
protected DirectoryReader doOpenIfChanged() {
throw new UnsupportedOperationException();
}
@Override
protected DirectoryReader doOpenIfChanged(IndexCommit commit) {
throw new UnsupportedOperationException();
}
@Override
protected DirectoryReader doOpenIfChanged(IndexWriter writer, boolean applyAllDeletes) {
throw new UnsupportedOperationException();
}
@Override
public long getVersion() {
throw new UnsupportedOperationException();
}
@Override
public boolean isCurrent() {
throw new UnsupportedOperationException();
}
@Override
public IndexCommit getIndexCommit() {
throw new UnsupportedOperationException();
}
@Override
protected void doClose() {
throw new UnsupportedOperationException();
}
@Override
public CacheHelper getReaderCacheHelper() {
throw new UnsupportedOperationException();
}
// except of a couple of selected methods everything else will
// throw a UOE which causes a can_match phase to just move to the actual phase
// later such that we never false exclude a shard if something else is used to rewrite.
private static final class RewriteCachingLeafReader extends LeafReader {
private final int maxDoc;
private final int numDocs;
private final Map pointValuesMap;
private final FieldInfos fieldInfos;
private RewriteCachingLeafReader(LeafReader original) throws IOException {
this.maxDoc = original.maxDoc();
this.numDocs = original.numDocs();
fieldInfos = original.getFieldInfos();
Map valuesMap = new HashMap<>();
for (FieldInfo info : fieldInfos) {
if (info.getPointIndexDimensionCount() != 0) {
PointValues pointValues = original.getPointValues(info.name);
if (pointValues != null) { // might not be in this reader
byte[] minPackedValue = pointValues.getMinPackedValue();
byte[] maxPackedValue = pointValues.getMaxPackedValue();
int numIndexDimensions = pointValues.getNumIndexDimensions();
int bytesPerDimension = pointValues.getBytesPerDimension();
int numDimensions = pointValues.getNumDimensions();
long size = pointValues.size();
int docCount = pointValues.getDocCount();
valuesMap.put(info.name, new PointValues() {
@Override
public void intersect(IntersectVisitor visitor) {
throw new UnsupportedOperationException();
}
@Override
public long estimatePointCount(IntersectVisitor visitor) {
throw new UnsupportedOperationException();
}
@Override
public byte[] getMinPackedValue() {
return minPackedValue;
}
@Override
public byte[] getMaxPackedValue() {
return maxPackedValue;
}
@Override
public int getNumDimensions() {
return numDimensions;
}
@Override
public int getNumIndexDimensions() {
return numIndexDimensions;
}
@Override
public int getBytesPerDimension() {
return bytesPerDimension;
}
@Override
public long size() {
return size;
}
@Override
public int getDocCount() {
return docCount;
}
});
}
}
}
pointValuesMap = valuesMap;
}
@Override
public CacheHelper getCoreCacheHelper() {
throw new UnsupportedOperationException();
}
@Override
public Terms terms(String field) {
throw new UnsupportedOperationException();
}
@Override
public NumericDocValues getNumericDocValues(String field) {
throw new UnsupportedOperationException();
}
@Override
public BinaryDocValues getBinaryDocValues(String field) {
throw new UnsupportedOperationException();
}
@Override
public SortedDocValues getSortedDocValues(String field) {
throw new UnsupportedOperationException();
}
@Override
public SortedNumericDocValues getSortedNumericDocValues(String field) {
throw new UnsupportedOperationException();
}
@Override
public SortedSetDocValues getSortedSetDocValues(String field) {
throw new UnsupportedOperationException();
}
@Override
public NumericDocValues getNormValues(String field) {
throw new UnsupportedOperationException();
}
@Override
public FieldInfos getFieldInfos() {
return fieldInfos;
}
@Override
public Bits getLiveDocs() {
throw new UnsupportedOperationException();
}
@Override
public PointValues getPointValues(String field) {
return pointValuesMap.get(field);
}
@Override
public void checkIntegrity() {
}
@Override
public LeafMetaData getMetaData() {
throw new UnsupportedOperationException();
}
@Override
public Fields getTermVectors(int docID) {
throw new UnsupportedOperationException();
}
@Override
public int numDocs() {
return numDocs;
}
@Override
public int maxDoc() {
return maxDoc;
}
@Override
public void document(int docID, StoredFieldVisitor visitor) {
throw new UnsupportedOperationException();
}
@Override
protected void doClose() {
}
@Override
public CacheHelper getReaderCacheHelper() {
return null;
}
}
}