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 org.apache.hadoop.hbase.HConstants; 022import org.apache.hbase.thirdparty.com.google.common.annotations.VisibleForTesting; 023import java.util.Collection; 024import java.util.Comparator; 025import java.util.Iterator; 026import java.util.NavigableSet; 027import java.util.NavigableMap; 028import java.util.SortedSet; 029import java.util.concurrent.ConcurrentSkipListMap; 030 031import org.apache.hadoop.hbase.Cell; 032import org.apache.hadoop.hbase.CellComparator; 033import org.apache.yetus.audience.InterfaceAudience; 034 035/** 036 * A {@link java.util.Set} of {@link Cell}s, where an add will overwrite the entry if already 037 * exists in the set. The call to add returns true if no value in the backing map or false if 038 * there was an entry with same key (though value may be different). 039 * implementation is tolerant of concurrent get and set and won't throw 040 * ConcurrentModificationException when iterating. 041 */ 042@InterfaceAudience.Private 043public class CellSet implements NavigableSet<Cell> { 044 045 public static final int UNKNOWN_NUM_UNIQUES = -1; 046 // Implemented on top of a {@link java.util.concurrent.ConcurrentSkipListMap} 047 // Differ from CSLS in one respect, where CSLS does "Adds the specified element to this set if it 048 // is not already present.", this implementation "Adds the specified element to this set EVEN 049 // if it is already present overwriting what was there previous". 050 // Otherwise, has same attributes as ConcurrentSkipListSet 051 private final NavigableMap<Cell, Cell> delegatee; /// 052 053 private final int numUniqueKeys; 054 055 CellSet(final CellComparator c) { 056 this.delegatee = new ConcurrentSkipListMap<>(c.getSimpleComparator()); 057 this.numUniqueKeys = UNKNOWN_NUM_UNIQUES; 058 } 059 060 CellSet(final NavigableMap<Cell, Cell> m, int numUniqueKeys) { 061 this.delegatee = m; 062 this.numUniqueKeys = numUniqueKeys; 063 } 064 065 @VisibleForTesting 066 CellSet(final NavigableMap<Cell, Cell> m) { 067 this.delegatee = m; 068 this.numUniqueKeys = UNKNOWN_NUM_UNIQUES; 069 } 070 071 @VisibleForTesting 072 NavigableMap<Cell, Cell> getDelegatee() { 073 return delegatee; 074 } 075 076 @Override 077 public Cell ceiling(Cell e) { 078 throw new UnsupportedOperationException(HConstants.NOT_IMPLEMENTED); 079 } 080 081 @Override 082 public Iterator<Cell> descendingIterator() { 083 return this.delegatee.descendingMap().values().iterator(); 084 } 085 086 @Override 087 public NavigableSet<Cell> descendingSet() { 088 throw new UnsupportedOperationException(HConstants.NOT_IMPLEMENTED); 089 } 090 091 @Override 092 public Cell floor(Cell e) { 093 throw new UnsupportedOperationException(HConstants.NOT_IMPLEMENTED); 094 } 095 096 @Override 097 public SortedSet<Cell> headSet(final Cell toElement) { 098 return headSet(toElement, false); 099 } 100 101 @Override 102 public NavigableSet<Cell> headSet(final Cell toElement, 103 boolean inclusive) { 104 return new CellSet(this.delegatee.headMap(toElement, inclusive), UNKNOWN_NUM_UNIQUES); 105 } 106 107 @Override 108 public Cell higher(Cell e) { 109 throw new UnsupportedOperationException(HConstants.NOT_IMPLEMENTED); 110 } 111 112 @Override 113 public Iterator<Cell> iterator() { 114 return this.delegatee.values().iterator(); 115 } 116 117 @Override 118 public Cell lower(Cell e) { 119 throw new UnsupportedOperationException(HConstants.NOT_IMPLEMENTED); 120 } 121 122 @Override 123 public Cell pollFirst() { 124 throw new UnsupportedOperationException(HConstants.NOT_IMPLEMENTED); 125 } 126 127 @Override 128 public Cell pollLast() { 129 throw new UnsupportedOperationException(HConstants.NOT_IMPLEMENTED); 130 } 131 132 @Override 133 public SortedSet<Cell> subSet(Cell fromElement, Cell toElement) { 134 throw new UnsupportedOperationException(HConstants.NOT_IMPLEMENTED); 135 } 136 137 @Override 138 public NavigableSet<Cell> subSet(Cell fromElement, 139 boolean fromInclusive, Cell toElement, boolean toInclusive) { 140 throw new UnsupportedOperationException(HConstants.NOT_IMPLEMENTED); 141 } 142 143 @Override 144 public SortedSet<Cell> tailSet(Cell fromElement) { 145 return tailSet(fromElement, true); 146 } 147 148 @Override 149 public NavigableSet<Cell> tailSet(Cell fromElement, boolean inclusive) { 150 return new CellSet(this.delegatee.tailMap(fromElement, inclusive), UNKNOWN_NUM_UNIQUES); 151 } 152 153 @Override 154 public Comparator<? super Cell> comparator() { 155 throw new UnsupportedOperationException(HConstants.NOT_IMPLEMENTED); 156 } 157 158 @Override 159 public Cell first() { 160 return this.delegatee.firstEntry().getValue(); 161 } 162 163 @Override 164 public Cell last() { 165 return this.delegatee.lastEntry().getValue(); 166 } 167 168 @Override 169 public boolean add(Cell e) { 170 return this.delegatee.put(e, e) == null; 171 } 172 173 @Override 174 public boolean addAll(Collection<? extends Cell> c) { 175 throw new UnsupportedOperationException(HConstants.NOT_IMPLEMENTED); 176 } 177 178 @Override 179 public void clear() { 180 this.delegatee.clear(); 181 } 182 183 @Override 184 public boolean contains(Object o) { 185 //noinspection SuspiciousMethodCalls 186 return this.delegatee.containsKey(o); 187 } 188 189 @Override 190 public boolean containsAll(Collection<?> c) { 191 throw new UnsupportedOperationException(HConstants.NOT_IMPLEMENTED); 192 } 193 194 @Override 195 public boolean isEmpty() { 196 return this.delegatee.isEmpty(); 197 } 198 199 @Override 200 public boolean remove(Object o) { 201 return this.delegatee.remove(o) != null; 202 } 203 204 @Override 205 public boolean removeAll(Collection<?> c) { 206 throw new UnsupportedOperationException(HConstants.NOT_IMPLEMENTED); 207 } 208 209 @Override 210 public boolean retainAll(Collection<?> c) { 211 throw new UnsupportedOperationException(HConstants.NOT_IMPLEMENTED); 212 } 213 214 public Cell get(Cell kv) { 215 return this.delegatee.get(kv); 216 } 217 218 @Override 219 public int size() { 220 if (delegatee instanceof ConcurrentSkipListMap) { 221 throw new UnsupportedOperationException("ConcurrentSkipListMap.size() is time-consuming"); 222 } 223 return this.delegatee.size(); 224 } 225 226 @Override 227 public Object[] toArray() { 228 throw new UnsupportedOperationException(HConstants.NOT_IMPLEMENTED); 229 } 230 231 @Override 232 public <T> T[] toArray(T[] a) { 233 throw new UnsupportedOperationException(HConstants.NOT_IMPLEMENTED); 234 } 235 236 public int getNumUniqueKeys() { 237 return numUniqueKeys; 238 } 239}