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