All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.elasticsearch.xpack.searchablesnapshots.SearchableSnapshotsUtils 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.xpack.searchablesnapshots;

import org.apache.lucene.index.IndexCommit;
import org.apache.lucene.index.IndexFileNames;
import org.apache.lucene.index.SegmentInfos;
import org.apache.lucene.store.Directory;
import org.apache.lucene.util.Version;
import org.elasticsearch.common.lucene.Lucene;
import org.elasticsearch.common.unit.ByteSizeUnit;

import java.io.IOException;
import java.io.UncheckedIOException;
import java.util.Arrays;
import java.util.Comparator;

public class SearchableSnapshotsUtils {

    static final Comparator SEGMENT_FILENAME_COMPARATOR = Comparator.comparingLong(SegmentInfos::generationFromSegmentsFileName);

    public static IndexCommit emptyIndexCommit(Directory directory) {
        try {
            // We have to use a generation number that corresponds to a real segments_N file since we read this file from
            // the directory during the snapshotting process. The oldest segments_N file is the one in the snapshot
            // (recalling that we may perform some no-op commits which make newer segments_N files too). The good thing
            // about using the oldest segments_N file is that a restore will find that we already have this file "locally",
            // avoid overwriting the real one with the bogus one, and then use the real one for the rest of the recovery.
            final String oldestSegmentsFile = Arrays.stream(directory.listAll())
                    .filter(s -> s.startsWith(IndexFileNames.SEGMENTS + "_"))
                    .min(SEGMENT_FILENAME_COMPARATOR)
                    .orElseThrow(() -> new IOException("segments_N file not found"));
            final SegmentInfos segmentInfos = new SegmentInfos(Version.LATEST.major);
            segmentInfos.updateGeneration(SegmentInfos.readCommit(directory, oldestSegmentsFile));
            return Lucene.getIndexCommit(segmentInfos, directory);
        } catch (IOException e) {
            throw new UncheckedIOException(e);
        }
    }

    /**
     * We use {@code long} to represent offsets and lengths of files since they may be larger than 2GB, but {@code int} to represent
     * offsets and lengths of arrays in memory which are limited to 2GB in size. We quite often need to convert from the file-based world
     * of {@code long}s into the memory-based world of {@code int}s, knowing for certain that the result will not overflow. This method
     * should be used to clarify that we're doing this.
     */
    public static int toIntBytes(long l) {
        return ByteSizeUnit.BYTES.toIntBytes(l);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy