001/** 002 * 003 * Licensed to the Apache Software Foundation (ASF) under one 004 * or more contributor license agreements. See the NOTICE file 005 * distributed with this work for additional information 006 * regarding copyright ownership. The ASF licenses this file 007 * to you under the Apache License, Version 2.0 (the 008 * "License"); you may not use this file except in compliance 009 * with the License. You may obtain a copy of the License at 010 * 011 * http://www.apache.org/licenses/LICENSE-2.0 012 * 013 * Unless required by applicable law or agreed to in writing, software 014 * distributed under the License is distributed on an "AS IS" BASIS, 015 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 016 * See the License for the specific language governing permissions and 017 * limitations under the License. 018 */ 019package org.apache.hadoop.hbase.regionserver; 020 021import java.util.List; 022import org.apache.yetus.audience.InterfaceAudience; 023 024import org.apache.hbase.thirdparty.com.google.common.annotations.VisibleForTesting; 025 026/** 027 * A list of segment managers coupled with the version of the memstore (version at the time it was 028 * created). 029 * This structure helps to guarantee that the compaction pipeline updates after the compaction is 030 * updated in a consistent (atomic) way. 031 * Specifically, swapping some of the elements in a compaction pipeline with a new compacted 032 * element is permitted only if the pipeline version is the same as the version attached to the 033 * elements. 034 * 035 */ 036@InterfaceAudience.Private 037public class VersionedSegmentsList { 038 039 private final List<ImmutableSegment> storeSegments; 040 private final long version; 041 042 public VersionedSegmentsList(List<ImmutableSegment> storeSegments, long version) { 043 this.storeSegments = storeSegments; 044 this.version = version; 045 } 046 047 public List<ImmutableSegment> getStoreSegments() { 048 return storeSegments; 049 } 050 051 public long getVersion() { 052 return version; 053 } 054 055 public int getNumOfCells() { 056 int totalCells = 0; 057 for (ImmutableSegment s : storeSegments) { 058 totalCells += s.getCellsCount(); 059 } 060 return totalCells; 061 } 062 063 public int getNumOfSegments() { 064 return storeSegments.size(); 065 } 066 067 // Estimates fraction of unique keys 068 @VisibleForTesting 069 double getEstimatedUniquesFrac() { 070 int segmentCells = 0; 071 int maxCells = 0; 072 double est = 0; 073 074 for (ImmutableSegment s : storeSegments) { 075 double segmentUniques = s.getNumUniqueKeys(); 076 if(segmentUniques != CellSet.UNKNOWN_NUM_UNIQUES) { 077 segmentCells = s.getCellsCount(); 078 if(segmentCells > maxCells) { 079 maxCells = segmentCells; 080 est = segmentUniques / segmentCells; 081 } 082 } 083 // else ignore this segment specifically since if the unique number is unknown counting 084 // cells can be expensive 085 } 086 if(maxCells == 0) { 087 return 1.0; 088 } 089 return est; 090 } 091}