001/**
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements.  See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership.  The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 *
010 *     http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018package org.apache.hadoop.hbase.regionserver;
019
020import org.apache.hbase.thirdparty.com.google.common.base.Function;
021import org.apache.hbase.thirdparty.com.google.common.collect.ImmutableList;
022import org.apache.hbase.thirdparty.com.google.common.collect.Ordering;
023
024import java.util.Comparator;
025
026import org.apache.yetus.audience.InterfaceAudience;
027
028/**
029 * Useful comparators for comparing store files.
030 */
031@InterfaceAudience.Private
032final class StoreFileComparators {
033  /**
034   * Comparator that compares based on the Sequence Ids of the the store files. Bulk loads that did
035   * not request a seq ID are given a seq id of -1; thus, they are placed before all non- bulk
036   * loads, and bulk loads with sequence Id. Among these files, the size is used to determine the
037   * ordering, then bulkLoadTime. If there are ties, the path name is used as a tie-breaker.
038   */
039  public static final Comparator<HStoreFile> SEQ_ID =
040      Ordering.compound(ImmutableList.of(Ordering.natural().onResultOf(new GetSeqId()),
041        Ordering.natural().onResultOf(new GetFileSize()).reverse(),
042        Ordering.natural().onResultOf(new GetBulkTime()),
043        Ordering.natural().onResultOf(new GetPathName())));
044
045  /**
046   * Comparator for time-aware compaction. SeqId is still the first ordering criterion to maintain
047   * MVCC.
048   */
049  public static final Comparator<HStoreFile> SEQ_ID_MAX_TIMESTAMP =
050      Ordering.compound(ImmutableList.of(Ordering.natural().onResultOf(new GetSeqId()),
051        Ordering.natural().onResultOf(new GetMaxTimestamp()),
052        Ordering.natural().onResultOf(new GetFileSize()).reverse(),
053        Ordering.natural().onResultOf(new GetBulkTime()),
054        Ordering.natural().onResultOf(new GetPathName())));
055
056  private static class GetSeqId implements Function<HStoreFile, Long> {
057    @Override
058    public Long apply(HStoreFile sf) {
059      return sf.getMaxSequenceId();
060    }
061  }
062
063  private static class GetFileSize implements Function<HStoreFile, Long> {
064    @Override
065    public Long apply(HStoreFile sf) {
066      if (sf.getReader() != null) {
067        return sf.getReader().length();
068      } else {
069        // the reader may be null for the compacted files and if the archiving
070        // had failed.
071        return -1L;
072      }
073    }
074  }
075
076  private static class GetBulkTime implements Function<HStoreFile, Long> {
077    @Override
078    public Long apply(HStoreFile sf) {
079      return sf.getBulkLoadTimestamp().orElse(Long.MAX_VALUE);
080    }
081  }
082
083  private static class GetPathName implements Function<HStoreFile, String> {
084    @Override
085    public String apply(HStoreFile sf) {
086      return sf.getPath().getName();
087    }
088  }
089
090  private static class GetMaxTimestamp implements Function<HStoreFile, Long> {
091    @Override
092    public Long apply(HStoreFile sf) {
093      return sf.getMaximumTimestamp().orElse(Long.MAX_VALUE);
094    }
095  }
096}