Example usage for org.apache.lucene.store IndexInput readVLong

List of usage examples for org.apache.lucene.store IndexInput readVLong

Introduction

In this page you can find the example usage for org.apache.lucene.store IndexInput readVLong.

Prototype

public long readVLong() throws IOException 

Source Link

Document

Reads a long stored in variable-length format.

Usage

From source file:com.lucure.core.codec.CompressingStoredFieldsIndexReader.java

License:Apache License

CompressingStoredFieldsIndexReader(IndexInput fieldsIndexIn, SegmentInfo si) throws IOException {
    maxDoc = si.getDocCount();/*from  ww  w .j a v a  2  s . com*/
    int[] docBases = new int[16];
    long[] startPointers = new long[16];
    int[] avgChunkDocs = new int[16];
    long[] avgChunkSizes = new long[16];
    PackedInts.Reader[] docBasesDeltas = new PackedInts.Reader[16];
    PackedInts.Reader[] startPointersDeltas = new PackedInts.Reader[16];

    final int packedIntsVersion = fieldsIndexIn.readVInt();

    int blockCount = 0;

    for (;;) {
        final int numChunks = fieldsIndexIn.readVInt();
        if (numChunks == 0) {
            break;
        }
        if (blockCount == docBases.length) {
            final int newSize = ArrayUtil.oversize(blockCount + 1, 8);
            docBases = Arrays.copyOf(docBases, newSize);
            startPointers = Arrays.copyOf(startPointers, newSize);
            avgChunkDocs = Arrays.copyOf(avgChunkDocs, newSize);
            avgChunkSizes = Arrays.copyOf(avgChunkSizes, newSize);
            docBasesDeltas = Arrays.copyOf(docBasesDeltas, newSize);
            startPointersDeltas = Arrays.copyOf(startPointersDeltas, newSize);
        }

        // doc bases
        docBases[blockCount] = fieldsIndexIn.readVInt();
        avgChunkDocs[blockCount] = fieldsIndexIn.readVInt();
        final int bitsPerDocBase = fieldsIndexIn.readVInt();
        if (bitsPerDocBase > 32) {
            throw new CorruptIndexException("Corrupted bitsPerDocBase (resource=" + fieldsIndexIn + ")");
        }
        docBasesDeltas[blockCount] = PackedInts.getReaderNoHeader(fieldsIndexIn, PackedInts.Format.PACKED,
                packedIntsVersion, numChunks, bitsPerDocBase);

        // start pointers
        startPointers[blockCount] = fieldsIndexIn.readVLong();
        avgChunkSizes[blockCount] = fieldsIndexIn.readVLong();
        final int bitsPerStartPointer = fieldsIndexIn.readVInt();
        if (bitsPerStartPointer > 64) {
            throw new CorruptIndexException("Corrupted bitsPerStartPointer (resource=" + fieldsIndexIn + ")");
        }
        startPointersDeltas[blockCount] = PackedInts.getReaderNoHeader(fieldsIndexIn, PackedInts.Format.PACKED,
                packedIntsVersion, numChunks, bitsPerStartPointer);

        ++blockCount;
    }

    this.docBases = Arrays.copyOf(docBases, blockCount);
    this.startPointers = Arrays.copyOf(startPointers, blockCount);
    this.avgChunkDocs = Arrays.copyOf(avgChunkDocs, blockCount);
    this.avgChunkSizes = Arrays.copyOf(avgChunkSizes, blockCount);
    this.docBasesDeltas = Arrays.copyOf(docBasesDeltas, blockCount);
    this.startPointersDeltas = Arrays.copyOf(startPointersDeltas, blockCount);
}

From source file:com.rocana.lucene.codec.v1.RocanaBlockTreeTermsReader.java

License:Apache License

/** Sole constructor. */
public RocanaBlockTreeTermsReader(PostingsReaderBase postingsReader, SegmentReadState state)
        throws IOException {
    boolean success = false;
    IndexInput indexIn = null;

    this.postingsReader = postingsReader;
    this.segment = state.segmentInfo.name;

    String termsName = IndexFileNames.segmentFileName(segment, state.segmentSuffix, TERMS_EXTENSION);
    try {//w  ww  .  ja  v  a  2  s .  c  om
        termsIn = state.directory.openInput(termsName, state.context);
        version = CodecUtil.checkIndexHeader(termsIn, TERMS_CODEC_NAME, VERSION_START, VERSION_CURRENT,
                state.segmentInfo.getId(), state.segmentSuffix);

        if (version < VERSION_AUTO_PREFIX_TERMS) {
            // Old (pre-5.2.0) index, no auto-prefix terms:
            this.anyAutoPrefixTerms = false;
        } else if (version == VERSION_AUTO_PREFIX_TERMS) {
            // 5.2.x index, might have auto-prefix terms:
            this.anyAutoPrefixTerms = true;
        } else {
            // 5.3.x index, we record up front if we may have written any auto-prefix terms:
            assert version >= VERSION_AUTO_PREFIX_TERMS_COND;
            byte b = termsIn.readByte();
            if (b == 0) {
                this.anyAutoPrefixTerms = false;
            } else if (b == 1) {
                this.anyAutoPrefixTerms = true;
            } else {
                throw new CorruptIndexException("invalid anyAutoPrefixTerms: expected 0 or 1 but got " + b,
                        termsIn);
            }
        }

        String indexName = IndexFileNames.segmentFileName(segment, state.segmentSuffix, TERMS_INDEX_EXTENSION);
        indexIn = state.directory.openInput(indexName, state.context);
        CodecUtil.checkIndexHeader(indexIn, TERMS_INDEX_CODEC_NAME, version, version, state.segmentInfo.getId(),
                state.segmentSuffix);

        // IMPORTANT: comment out this one line to prevent checksumming the entire file.
        //            This is the reason we have a custom Lucene codec and forked Lucene classes.
        //CodecUtil.checksumEntireFile(indexIn);

        // Have PostingsReader init itself
        postingsReader.init(termsIn, state);

        // NOTE: data file is too costly to verify checksum against all the bytes on open,
        // but for now we at least verify proper structure of the checksum footer: which looks
        // for FOOTER_MAGIC + algorithmID. This is cheap and can detect some forms of corruption
        // such as file truncation.
        CodecUtil.retrieveChecksum(termsIn);

        // Read per-field details
        seekDir(termsIn, dirOffset);
        seekDir(indexIn, indexDirOffset);

        final int numFields = termsIn.readVInt();
        if (numFields < 0) {
            throw new CorruptIndexException("invalid numFields: " + numFields, termsIn);
        }

        for (int i = 0; i < numFields; ++i) {
            final int field = termsIn.readVInt();
            final long numTerms = termsIn.readVLong();
            if (numTerms <= 0) {
                throw new CorruptIndexException("Illegal numTerms for field number: " + field, termsIn);
            }
            final int numBytes = termsIn.readVInt();
            if (numBytes < 0) {
                throw new CorruptIndexException(
                        "invalid rootCode for field number: " + field + ", numBytes=" + numBytes, termsIn);
            }
            final BytesRef rootCode = new BytesRef(new byte[numBytes]);
            termsIn.readBytes(rootCode.bytes, 0, numBytes);
            rootCode.length = numBytes;
            final FieldInfo fieldInfo = state.fieldInfos.fieldInfo(field);
            if (fieldInfo == null) {
                throw new CorruptIndexException("invalid field number: " + field, termsIn);
            }
            final long sumTotalTermFreq = fieldInfo.getIndexOptions() == IndexOptions.DOCS ? -1
                    : termsIn.readVLong();
            final long sumDocFreq = termsIn.readVLong();
            final int docCount = termsIn.readVInt();
            final int longsSize = termsIn.readVInt();
            if (longsSize < 0) {
                throw new CorruptIndexException(
                        "invalid longsSize for field: " + fieldInfo.name + ", longsSize=" + longsSize, termsIn);
            }
            BytesRef minTerm = readBytesRef(termsIn);
            BytesRef maxTerm = readBytesRef(termsIn);
            if (docCount < 0 || docCount > state.segmentInfo.maxDoc()) { // #docs with field must be <= #docs
                throw new CorruptIndexException(
                        "invalid docCount: " + docCount + " maxDoc: " + state.segmentInfo.maxDoc(), termsIn);
            }
            if (sumDocFreq < docCount) { // #postings must be >= #docs with field
                throw new CorruptIndexException("invalid sumDocFreq: " + sumDocFreq + " docCount: " + docCount,
                        termsIn);
            }
            if (sumTotalTermFreq != -1 && sumTotalTermFreq < sumDocFreq) { // #positions must be >= #postings
                throw new CorruptIndexException(
                        "invalid sumTotalTermFreq: " + sumTotalTermFreq + " sumDocFreq: " + sumDocFreq,
                        termsIn);
            }
            final long indexStartFP = indexIn.readVLong();
            RocanaFieldReader previous = fields.put(fieldInfo.name,
                    new RocanaFieldReader(this, fieldInfo, numTerms, rootCode, sumTotalTermFreq, sumDocFreq,
                            docCount, indexStartFP, longsSize, indexIn, minTerm, maxTerm));
            if (previous != null) {
                throw new CorruptIndexException("duplicate field: " + fieldInfo.name, termsIn);
            }
        }

        indexIn.close();
        success = true;
    } finally {
        if (!success) {
            // this.close() will close in:
            IOUtils.closeWhileHandlingException(indexIn, this);
        }
    }
}

From source file:org.apache.blur.lucene.codec.DiskDocValuesProducer.java

License:Apache License

static NumericEntry readNumericEntry(IndexInput meta) throws IOException {
    NumericEntry entry = new NumericEntry();
    entry.packedIntsVersion = meta.readVInt();
    entry.offset = meta.readLong();/*  w  w  w.  j av a2s  .  c o m*/
    entry.count = meta.readVLong();
    entry.blockSize = meta.readVInt();
    return entry;
}

From source file:org.apache.blur.lucene.codec.DiskDocValuesProducer.java

License:Apache License

static BinaryEntry readBinaryEntry(IndexInput meta) throws IOException {
    BinaryEntry entry = new BinaryEntry();
    entry.minLength = meta.readVInt();/*from   ww w  .  ja v a  2  s .c  o  m*/
    entry.maxLength = meta.readVInt();
    entry.count = meta.readVLong();
    entry.offset = meta.readLong();
    if (entry.minLength != entry.maxLength) {
        entry.addressesOffset = meta.readLong();
        entry.packedIntsVersion = meta.readVInt();
        entry.blockSize = meta.readVInt();
    }
    return entry;
}

From source file:org.apache.blur.lucene.warmup.IndexTracerResult.java

License:Apache License

public static IndexTracerResult read(IndexInput input) throws IOException {

    IndexTracerResult result = new IndexTracerResult();

    result._field = input.readString();//from  w  ww . ja  v a 2s .c o  m
    result._segmentName = input.readString();

    result._timCaptured = readBoolean(input);
    if (result._timCaptured) {
        result._timPosition = input.readVLong();
        result._timFileName = input.readString();
    }

    result._docCaptured = readBoolean(input);
    if (result._docCaptured) {
        result._docPosition = input.readVLong();
        result._docFileName = input.readString();
    }

    result._posCaptured = readBoolean(input);
    if (result._posCaptured) {
        result._posPosition = input.readVLong();
        result._posFileName = input.readString();
    }

    result._payCaptured = readBoolean(input);
    if (result._payCaptured) {
        result._payPosition = input.readVLong();
        result._payFileName = input.readString();
    }
    return result;
}

From source file:org.apache.jackrabbit.oak.plugins.index.lucene.OakDirectoryTest.java

License:Apache License

private void assertClosed(IndexInput input) throws IOException {
    try {/*from w  w  w  .  ja  v  a 2 s  . c o m*/
        input.length();
        fail("cannot use IndexInput once closed");
    } catch (AlreadyClosedException e) {
        // expected exception
    }
    try {
        input.seek(0);
        fail("cannot use IndexInput once closed");
    } catch (AlreadyClosedException e) {
        // expected exception
    }
    try {
        input.getFilePointer();
        fail("cannot use IndexInput once closed");
    } catch (AlreadyClosedException e) {
        // expected exception
    }
    try {
        input.readInt();
        fail("cannot use IndexInput once closed");
    } catch (AlreadyClosedException e) {
        // expected exception
    }
    try {
        input.readShort();
        fail("cannot use IndexInput once closed");
    } catch (AlreadyClosedException e) {
        // expected exception
    }
    try {
        input.readLong();
        fail("cannot use IndexInput once closed");
    } catch (AlreadyClosedException e) {
        // expected exception
    }
    try {
        input.readByte();
        fail("cannot use IndexInput once closed");
    } catch (AlreadyClosedException e) {
        // expected exception
    }
    try {
        input.readString();
        fail("cannot use IndexInput once closed");
    } catch (AlreadyClosedException e) {
        // expected exception
    }
    try {
        input.readStringSet();
        fail("cannot use IndexInput once closed");
    } catch (AlreadyClosedException e) {
        // expected exception
    }
    try {
        input.readStringStringMap();
        fail("cannot use IndexInput once closed");
    } catch (AlreadyClosedException e) {
        // expected exception
    }
    try {
        input.readVInt();
        fail("cannot use IndexInput once closed");
    } catch (AlreadyClosedException e) {
        // expected exception
    }
    try {
        input.readVLong();
        fail("cannot use IndexInput once closed");
    } catch (AlreadyClosedException e) {
        // expected exception
    }
    try {
        input.readBytes(null, 0, 0);
        fail("cannot use IndexInput once closed");
    } catch (AlreadyClosedException e) {
        // expected exception
    }
    try {
        input.readBytes(null, 0, 0, false);
        fail("cannot use IndexInput once closed");
    } catch (AlreadyClosedException e) {
        // expected exception
    }
}

From source file:org.apache.solr.core.snapshots.SolrSnapshotMetaDataManager.java

License:Apache License

/**
 * Reads the snapshot meta-data information from the given {@link Directory}.
 *//* ww w  . j a v a2s.com*/
private synchronized void loadFromSnapshotMetadataFile() throws IOException {
    log.debug("Loading from snapshot metadata file...");
    long genLoaded = -1;
    IOException ioe = null;
    List<String> snapshotFiles = new ArrayList<>();
    for (String file : dir.listAll()) {
        if (file.startsWith(SNAPSHOTS_PREFIX)) {
            long gen = Long.parseLong(file.substring(SNAPSHOTS_PREFIX.length()));
            if (genLoaded == -1 || gen > genLoaded) {
                snapshotFiles.add(file);
                Map<String, SnapshotMetaData> snapshotMetaDataMapping = new HashMap<>();
                IndexInput in = dir.openInput(file, IOContext.DEFAULT);
                try {
                    CodecUtil.checkHeader(in, CODEC_NAME, VERSION_START, VERSION_START);
                    int count = in.readVInt();
                    for (int i = 0; i < count; i++) {
                        String name = in.readString();
                        String indexDirPath = in.readString();
                        long commitGen = in.readVLong();
                        snapshotMetaDataMapping.put(name, new SnapshotMetaData(name, indexDirPath, commitGen));
                    }
                } catch (IOException ioe2) {
                    // Save first exception & throw in the end
                    if (ioe == null) {
                        ioe = ioe2;
                    }
                } finally {
                    in.close();
                }

                genLoaded = gen;
                nameToDetailsMapping.clear();
                nameToDetailsMapping.putAll(snapshotMetaDataMapping);
            }
        }
    }

    if (genLoaded == -1) {
        // Nothing was loaded...
        if (ioe != null) {
            // ... not for lack of trying:
            throw ioe;
        }
    } else {
        if (snapshotFiles.size() > 1) {
            // Remove any broken / old snapshot files:
            String curFileName = SNAPSHOTS_PREFIX + genLoaded;
            for (String file : snapshotFiles) {
                if (!curFileName.equals(file)) {
                    IOUtils.deleteFilesIgnoringExceptions(dir, file);
                }
            }
        }
        nextWriteGen = 1 + genLoaded;
    }
}

From source file:org.elasticsearch.common.compress.CompressedIndexInput.java

License:Apache License

public CompressedIndexInput(IndexInput in, T context) throws IOException {
    super("compressed(" + in.toString() + ")");
    this.in = in;
    this.context = context;
    readHeader(in);//from  w  w w. j  av a  2  s .co  m
    this.version = in.readInt();
    long metaDataPosition = in.readLong();
    long headerLength = in.getFilePointer();
    in.seek(metaDataPosition);
    this.totalUncompressedLength = in.readVLong();
    int size = in.readVInt();
    offsets = BigArrays.newLongArray(size);
    for (int i = 0; i < size; i++) {
        offsets.set(i, in.readVLong());
    }
    this.currentOffsetIdx = -1;
    this.currentUncompressedChunkPointer = 0;
    in.seek(headerLength);
}

From source file:org.elasticsearch.search.suggest.completion.AnalyzingCompletionLookupProvider.java

License:Apache License

@Override
public LookupFactory load(IndexInput input) throws IOException {
    long sizeInBytes = 0;
    int version = CodecUtil.checkHeader(input, CODEC_NAME, CODEC_VERSION_START, CODEC_VERSION_LATEST);
    final Map<String, AnalyzingSuggestHolder> lookupMap = new HashMap<String, AnalyzingSuggestHolder>();
    input.seek(input.length() - 8);//from  www.  j  ava2s. co m
    long metaPointer = input.readLong();
    input.seek(metaPointer);
    int numFields = input.readVInt();

    Map<Long, String> meta = new TreeMap<Long, String>();
    for (int i = 0; i < numFields; i++) {
        String name = input.readString();
        long offset = input.readVLong();
        meta.put(offset, name);
    }

    for (Map.Entry<Long, String> entry : meta.entrySet()) {
        input.seek(entry.getKey());
        FST<Pair<Long, BytesRef>> fst = new FST<Pair<Long, BytesRef>>(input, new PairOutputs<Long, BytesRef>(
                PositiveIntOutputs.getSingleton(), ByteSequenceOutputs.getSingleton()));
        int maxAnalyzedPathsForOneInput = input.readVInt();
        int maxSurfaceFormsPerAnalyzedForm = input.readVInt();
        int maxGraphExpansions = input.readInt();
        int options = input.readVInt();
        boolean preserveSep = (options & SERIALIZE_PRESERVE_SEPERATORS) != 0;
        boolean hasPayloads = (options & SERIALIZE_HAS_PAYLOADS) != 0;
        boolean preservePositionIncrements = (options & SERIALIZE_PRESERVE_POSITION_INCREMENTS) != 0;

        // first version did not include these three fields, so fall back to old default (before the analyzingsuggester
        // was updated in Lucene, so we cannot use the suggester defaults)
        int sepLabel, payloadSep, endByte, holeCharacter;
        switch (version) {
        case CODEC_VERSION_START:
            sepLabel = 0xFF;
            payloadSep = '\u001f';
            endByte = 0x0;
            holeCharacter = '\u001E';
            break;
        default:
            sepLabel = input.readVInt();
            endByte = input.readVInt();
            payloadSep = input.readVInt();
            holeCharacter = input.readVInt();
        }

        AnalyzingSuggestHolder holder = new AnalyzingSuggestHolder(preserveSep, preservePositionIncrements,
                maxSurfaceFormsPerAnalyzedForm, maxGraphExpansions, hasPayloads, maxAnalyzedPathsForOneInput,
                fst, sepLabel, payloadSep, endByte, holeCharacter);
        sizeInBytes += fst.sizeInBytes();
        lookupMap.put(entry.getValue(), holder);
    }
    final long ramBytesUsed = sizeInBytes;
    return new LookupFactory() {
        @Override
        public Lookup getLookup(FieldMapper<?> mapper, CompletionSuggestionContext suggestionContext) {
            AnalyzingSuggestHolder analyzingSuggestHolder = lookupMap.get(mapper.names().indexName());
            if (analyzingSuggestHolder == null) {
                return null;
            }
            int flags = analyzingSuggestHolder.preserveSep ? XAnalyzingSuggester.PRESERVE_SEP : 0;

            XAnalyzingSuggester suggester;
            if (suggestionContext.isFuzzy()) {
                suggester = new XFuzzySuggester(mapper.indexAnalyzer(), mapper.searchAnalyzer(), flags,
                        analyzingSuggestHolder.maxSurfaceFormsPerAnalyzedForm,
                        analyzingSuggestHolder.maxGraphExpansions, suggestionContext.getFuzzyEditDistance(),
                        suggestionContext.isFuzzyTranspositions(), suggestionContext.getFuzzyPrefixLength(),
                        suggestionContext.getFuzzyMinLength(), suggestionContext.isFuzzyUnicodeAware(),
                        analyzingSuggestHolder.fst, analyzingSuggestHolder.hasPayloads,
                        analyzingSuggestHolder.maxAnalyzedPathsForOneInput, analyzingSuggestHolder.sepLabel,
                        analyzingSuggestHolder.payloadSep, analyzingSuggestHolder.endByte,
                        analyzingSuggestHolder.holeCharacter);

            } else {
                suggester = new XAnalyzingSuggester(mapper.indexAnalyzer(), mapper.searchAnalyzer(), flags,
                        analyzingSuggestHolder.maxSurfaceFormsPerAnalyzedForm,
                        analyzingSuggestHolder.maxGraphExpansions,
                        analyzingSuggestHolder.preservePositionIncrements, analyzingSuggestHolder.fst,
                        analyzingSuggestHolder.hasPayloads, analyzingSuggestHolder.maxAnalyzedPathsForOneInput,
                        analyzingSuggestHolder.sepLabel, analyzingSuggestHolder.payloadSep,
                        analyzingSuggestHolder.endByte, analyzingSuggestHolder.holeCharacter);
            }
            return suggester;
        }

        @Override
        public CompletionStats stats(String... fields) {
            long sizeInBytes = 0;
            ObjectLongOpenHashMap<String> completionFields = null;
            if (fields != null && fields.length > 0) {
                completionFields = new ObjectLongOpenHashMap<String>(fields.length);
            }

            for (Map.Entry<String, AnalyzingSuggestHolder> entry : lookupMap.entrySet()) {
                sizeInBytes += entry.getValue().fst.sizeInBytes();
                if (fields == null || fields.length == 0) {
                    continue;
                }
                for (String field : fields) {
                    // support for getting fields by regex as in fielddata
                    if (Regex.simpleMatch(field, entry.getKey())) {
                        long fstSize = entry.getValue().fst.sizeInBytes();
                        completionFields.addTo(field, fstSize);
                    }
                }
            }

            return new CompletionStats(sizeInBytes, completionFields);
        }

        @Override
        AnalyzingSuggestHolder getAnalyzingSuggestHolder(FieldMapper<?> mapper) {
            return lookupMap.get(mapper.names().indexName());
        }

        @Override
        public long ramBytesUsed() {
            return ramBytesUsed;
        }
    };
}

From source file:org.elasticsearch.search.suggest.completion.AnalyzingCompletionLookupProviderV1.java

License:Apache License

@Override
public LookupFactory load(IndexInput input) throws IOException {
    CodecUtil.checkHeader(input, CODEC_NAME, CODEC_VERSION, CODEC_VERSION);
    final Map<String, AnalyzingSuggestHolder> lookupMap = new HashMap<String, AnalyzingSuggestHolder>();
    input.seek(input.length() - 8);//from www . ja v a2s . c o m
    long metaPointer = input.readLong();
    input.seek(metaPointer);
    int numFields = input.readVInt();

    Map<Long, String> meta = new TreeMap<Long, String>();
    for (int i = 0; i < numFields; i++) {
        String name = input.readString();
        long offset = input.readVLong();
        meta.put(offset, name);
    }
    long sizeInBytes = 0;
    for (Map.Entry<Long, String> entry : meta.entrySet()) {
        input.seek(entry.getKey());
        FST<Pair<Long, BytesRef>> fst = new FST<Pair<Long, BytesRef>>(input, new PairOutputs<Long, BytesRef>(
                PositiveIntOutputs.getSingleton(), ByteSequenceOutputs.getSingleton()));
        int maxAnalyzedPathsForOneInput = input.readVInt();
        int maxSurfaceFormsPerAnalyzedForm = input.readVInt();
        int maxGraphExpansions = input.readInt();
        int options = input.readVInt();
        boolean preserveSep = (options & SERIALIZE_PRESERVE_SEPERATORS) != 0;
        boolean hasPayloads = (options & SERIALIZE_HAS_PAYLOADS) != 0;
        boolean preservePositionIncrements = (options & SERIALIZE_PRESERVE_POSITION_INCREMENTS) != 0;
        sizeInBytes += fst.sizeInBytes();
        lookupMap.put(entry.getValue(),
                new AnalyzingSuggestHolder(preserveSep, preservePositionIncrements,
                        maxSurfaceFormsPerAnalyzedForm, maxGraphExpansions, hasPayloads,
                        maxAnalyzedPathsForOneInput, fst));
    }
    final long ramBytesUsed = sizeInBytes;
    return new LookupFactory() {
        @Override
        public Lookup getLookup(FieldMapper<?> mapper, CompletionSuggestionContext suggestionContext) {
            AnalyzingSuggestHolder analyzingSuggestHolder = lookupMap.get(mapper.names().indexName());
            if (analyzingSuggestHolder == null) {
                return null;
            }
            int flags = analyzingSuggestHolder.preserveSep ? XAnalyzingSuggester.PRESERVE_SEP : 0;

            XAnalyzingSuggester suggester;
            if (suggestionContext.isFuzzy()) {
                suggester = new XFuzzySuggester(mapper.indexAnalyzer(), mapper.searchAnalyzer(), flags,
                        analyzingSuggestHolder.maxSurfaceFormsPerAnalyzedForm,
                        analyzingSuggestHolder.maxGraphExpansions, suggestionContext.getFuzzyEditDistance(),
                        suggestionContext.isFuzzyTranspositions(), suggestionContext.getFuzzyPrefixLength(),
                        suggestionContext.getFuzzyMinLength(), false, analyzingSuggestHolder.fst,
                        analyzingSuggestHolder.hasPayloads, analyzingSuggestHolder.maxAnalyzedPathsForOneInput,
                        SEP_LABEL, PAYLOAD_SEP, END_BYTE, XAnalyzingSuggester.HOLE_CHARACTER);

            } else {
                suggester = new XAnalyzingSuggester(mapper.indexAnalyzer(), mapper.searchAnalyzer(), flags,
                        analyzingSuggestHolder.maxSurfaceFormsPerAnalyzedForm,
                        analyzingSuggestHolder.maxGraphExpansions,
                        analyzingSuggestHolder.preservePositionIncrements, analyzingSuggestHolder.fst,
                        analyzingSuggestHolder.hasPayloads, analyzingSuggestHolder.maxAnalyzedPathsForOneInput,
                        SEP_LABEL, PAYLOAD_SEP, END_BYTE, XAnalyzingSuggester.HOLE_CHARACTER);
            }
            return suggester;
        }

        @Override
        public CompletionStats stats(String... fields) {
            long sizeInBytes = 0;
            ObjectLongOpenHashMap<String> completionFields = null;
            if (fields != null && fields.length > 0) {
                completionFields = new ObjectLongOpenHashMap<String>(fields.length);
            }

            for (Map.Entry<String, AnalyzingSuggestHolder> entry : lookupMap.entrySet()) {
                sizeInBytes += entry.getValue().fst.sizeInBytes();
                if (fields == null || fields.length == 0) {
                    continue;
                }
                for (String field : fields) {
                    // support for getting fields by regex as in fielddata
                    if (Regex.simpleMatch(field, entry.getKey())) {
                        long fstSize = entry.getValue().fst.sizeInBytes();
                        completionFields.addTo(field, fstSize);
                    }
                }
            }

            return new CompletionStats(sizeInBytes, completionFields);
        }

        @Override
        AnalyzingSuggestHolder getAnalyzingSuggestHolder(FieldMapper<?> mapper) {
            return lookupMap.get(mapper.names().indexName());
        }

        @Override
        public long ramBytesUsed() {
            return ramBytesUsed;
        }
    };
}