View Javadoc

1   /*
2    *
3    * Licensed to the Apache Software Foundation (ASF) under one
4    * or more contributor license agreements.  See the NOTICE file
5    * distributed with this work for additional information
6    * regarding copyright ownership.  The ASF licenses this file
7    * to you under the Apache License, Version 2.0 (the
8    * "License"); you may not use this file except in compliance
9    * with the License.  You may obtain a copy of the License at
10   *
11   *     http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing, software
14   * distributed under the License is distributed on an "AS IS" BASIS,
15   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16   * See the License for the specific language governing permissions and
17   * limitations under the License.
18   */
19  
20  package org.apache.hadoop.hbase.util;
21  
22  import java.util.Collection;
23  import java.util.Comparator;
24  import java.util.Iterator;
25  import java.util.SortedSet;
26  import java.util.TreeSet;
27  
28  import org.apache.hadoop.hbase.classification.InterfaceAudience;
29  
30  /**
31   * Simple {@link java.util.SortedSet} implementation that uses an internal
32   * {@link java.util.TreeSet} to provide ordering. All mutation operations
33   * create a new copy of the <code>TreeSet</code> instance, so are very
34   * expensive.  This class is only intended for use on small, very rarely
35   * written collections that expect highly concurrent reads. Read operations
36   * are performed on a reference to the internal <code>TreeSet</code> at the
37   * time of invocation, so will not see any mutations to the collection during
38   * their operation.
39   *
40   * <p>Note that due to the use of a {@link java.util.TreeSet} internally,
41   * a {@link java.util.Comparator} instance must be provided, or collection
42   * elements must implement {@link java.lang.Comparable}.
43   * </p>
44   * @param <E> A class implementing {@link java.lang.Comparable} or able to be
45   * compared by a provided comparator.
46   */
47  @InterfaceAudience.Private
48  public class SortedCopyOnWriteSet<E> implements SortedSet<E> {
49    private volatile SortedSet<E> internalSet;
50  
51    public SortedCopyOnWriteSet() {
52      this.internalSet = new TreeSet<E>();
53    }
54  
55    public SortedCopyOnWriteSet(Collection<? extends E> c) {
56      this.internalSet = new TreeSet<E>(c);
57    }
58  
59    public SortedCopyOnWriteSet(Comparator<? super E> comparator) {
60      this.internalSet = new TreeSet<E>(comparator);
61    }
62  
63    @Override
64    public int size() {
65      return internalSet.size();
66    }
67  
68    @Override
69    public boolean isEmpty() {
70      return internalSet.isEmpty();
71    }
72  
73    @Override
74    public boolean contains(Object o) {
75      return internalSet.contains(o);
76    }
77  
78    @Override
79    public Iterator<E> iterator() {
80      return internalSet.iterator();
81    }
82  
83    @Override
84    public Object[] toArray() {
85      return internalSet.toArray();
86    }
87  
88    @Override
89    public <T> T[] toArray(T[] a) {
90      return internalSet.toArray(a);
91    }
92  
93    @Override
94    public synchronized boolean add(E e) {
95      SortedSet<E> newSet = new TreeSet<E>(internalSet);
96      boolean added = newSet.add(e);
97      internalSet = newSet;
98      return added;
99    }
100 
101   @Override
102   public synchronized boolean remove(Object o) {
103     SortedSet<E> newSet = new TreeSet<E>(internalSet);
104     boolean removed = newSet.remove(o);
105     internalSet = newSet;
106     return removed;
107   }
108 
109   @Override
110   public boolean containsAll(Collection<?> c) {
111     return internalSet.containsAll(c);
112   }
113 
114   @Override
115   public synchronized boolean addAll(Collection<? extends E> c) {
116     SortedSet<E> newSet = new TreeSet<E>(internalSet);
117     boolean changed = newSet.addAll(c);
118     internalSet = newSet;
119     return changed;
120   }
121 
122   @Override
123   public synchronized boolean retainAll(Collection<?> c) {
124     SortedSet<E> newSet = new TreeSet<E>(internalSet);
125     boolean changed = newSet.retainAll(c);
126     internalSet = newSet;
127     return changed;
128   }
129 
130   @Override
131   public synchronized boolean removeAll(Collection<?> c) {
132     SortedSet<E> newSet = new TreeSet<E>(internalSet);
133     boolean changed = newSet.removeAll(c);
134     internalSet = newSet;
135     return changed;
136   }
137 
138   @Override
139   public synchronized void clear() {
140     Comparator<? super E> comparator = internalSet.comparator();
141     if (comparator != null) {
142       internalSet = new TreeSet<E>(comparator);
143     } else {
144       internalSet = new TreeSet<E>();
145     }
146   }
147 
148   @Override
149   public Comparator<? super E> comparator() {
150     return internalSet.comparator();
151   }
152 
153   @Override
154   public SortedSet<E> subSet(E fromElement, E toElement) {
155     return internalSet.subSet(fromElement, toElement);
156   }
157 
158   @Override
159   public SortedSet<E> headSet(E toElement) {
160     return internalSet.headSet(toElement);
161   }
162 
163   @Override
164   public SortedSet<E> tailSet(E fromElement) {
165     return internalSet.tailSet(fromElement);
166   }
167 
168   @Override
169   public E first() {
170     return internalSet.first();
171   }
172 
173   @Override
174   public E last() {
175     return internalSet.last();
176   }
177 }