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

org.apache.jackrabbit.oak.segment.file.Reclaimers Maven / Gradle / Ivy

There is a newer version: 1.72.0
Show newest version
/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.apache.jackrabbit.oak.segment.file;

import static com.google.common.base.Preconditions.checkNotNull;

import com.google.common.base.Predicate;
import org.apache.jackrabbit.oak.segment.compaction.SegmentGCOptions.GCType;
import org.apache.jackrabbit.oak.segment.file.tar.GCGeneration;
import org.jetbrains.annotations.NotNull;

/**
 * Helper class exposing static factories for reclaimers. A reclaimer
 * is a predicate used during the cleanup phase of garbage collection
 * to decide whether a segment of a given generation is reclaimable.
 */
class Reclaimers {

    private Reclaimers() {
        // Prevent instantiation.
    }

    /**
     * Create a reclaimer for segments of old generations. Whether a segment is considered old and
     * thus reclaimable depends on the type of the most recent GC operation and the number of
     * retained generations.
     * 

* In the case of {@link GCType#FULL FULL} a segment is reclaimable if its * {@link GCGeneration#getFullGeneration() full generation} is at least {@code retainedGenerations} * in the past wrt. {@code referenceGeneration} or if its * {@link GCGeneration#getGeneration() generation} is at least {@code retainedGenerations} in the * past wrt. {@code referenceGeneration} and it not a {@link GCGeneration#isCompacted() compacted segment}. *

* In the case of {@link GCType#TAIL TAIL} a segment is reclaimable if its * {@link GCGeneration#getGeneration() generation} is at least {@code retainedGenerations} in the * past wrt. {@code referenceGeneration} and the segment is not in the same tail as * segments of the {@code referenceGeneration}. A segment is in the same tail as another segment * if it is a {@link GCGeneration#isCompacted() compacted segment} and both segments have * the same {@code full generation}. * * @param lastGCType type of the most recent GC operation. {@link GCType#FULL} if unknown. * @param referenceGeneration generation used as reference for determining the age of other segments. * @param retainedGenerations number of generations to retain. */ static Predicate newOldReclaimer( @NotNull GCType lastGCType, @NotNull final GCGeneration referenceGeneration, int retainedGenerations) { switch (checkNotNull(lastGCType)) { case FULL: return newOldFullReclaimer(referenceGeneration, retainedGenerations); case TAIL: return newOldTailReclaimer(referenceGeneration, retainedGenerations); default: throw new IllegalArgumentException("Invalid gc type: " + lastGCType); } } private static Predicate newOldFullReclaimer( @NotNull final GCGeneration referenceGeneration, int retainedGenerations) { return new Predicate() { @Override public boolean apply(GCGeneration generation) { return isOldFull(generation) || (isOld(generation) && !generation.isCompacted()); } private boolean isOld(GCGeneration generation) { return referenceGeneration.compareWith(generation) >= retainedGenerations; } private boolean isOldFull(GCGeneration generation) { return referenceGeneration.compareFullGenerationWith(generation) >= retainedGenerations; } @Override public String toString() { return String.format( "(full generation older than %d.%d, with %d retained generations)", referenceGeneration.getGeneration(), referenceGeneration.getFullGeneration(), retainedGenerations ); } }; } private static Predicate newOldTailReclaimer( @NotNull final GCGeneration referenceGeneration, int retainedGenerations) { return new Predicate() { @Override public boolean apply(GCGeneration generation) { return isOld(generation) && !sameCompactedTail(generation); } private boolean isOld(GCGeneration generation) { return referenceGeneration.compareWith(generation) >= retainedGenerations; } private boolean sameCompactedTail(GCGeneration generation) { return generation.isCompacted() && generation.getFullGeneration() == referenceGeneration.getFullGeneration(); } @Override public String toString() { return String.format( "(generation older than %d.%d, with %d retained generations and not in the same compacted tail)", referenceGeneration.getGeneration(), referenceGeneration.getFullGeneration(), retainedGenerations ); } }; } /** * Create an exact reclaimer. An exact reclaimer reclaims only segment of on single generation. * @param referenceGeneration the generation to collect. * @return an new instance of an exact reclaimer for segments with their generation * matching {@code referenceGeneration}. */ static Predicate newExactReclaimer(@NotNull final GCGeneration referenceGeneration) { return new Predicate() { @Override public boolean apply(GCGeneration generation) { return generation.equals(referenceGeneration); } @Override public String toString() { return "(generation==" + referenceGeneration + ")"; } }; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy