1 /**
2  * Licensed to the Apache Software Foundation (ASF) under one
3  * or more contributor license agreements.  See the NOTICE file
4  * distributed with this work for additional information
5  * regarding copyright ownership.  The ASF licenses this file
6  * to you under the Apache License, Version 2.0 (the
7  * "License"); you may not use this file except in compliance
8  * with the License.  You may obtain a copy of the License at
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18 package org.apache.hadoop.hdfs.util;
19 
20 import java.util.Collection;
21 import java.util.Collections;
22 import java.util.Iterator;
23 import java.util.List;
24 import java.util.ListIterator;
25 
26 import org.apache.hadoop.classification.InterfaceAudience;
27 
28 /**
29  * A {@link ReadOnlyList} is a unmodifiable list,
30  * which supports read-only operations.
31  *
32  * @param <E> The type of the list elements.
33  */
34 @InterfaceAudience.Private
35 public interface ReadOnlyList<E> extends Iterable<E> {
36   /**
37    * Is this an empty list?
38    */
isEmpty()39   boolean isEmpty();
40 
41   /**
42    * @return the size of this list.
43    */
size()44   int size();
45 
46   /**
47    * @return the i-th element.
48    */
get(int i)49   E get(int i);
50 
51   /**
52    * Utilities for {@link ReadOnlyList}
53    */
54   public static class Util {
55     /** @return an empty list. */
emptyList()56     public static <E> ReadOnlyList<E> emptyList() {
57       return ReadOnlyList.Util.asReadOnlyList(Collections.<E>emptyList());
58     }
59 
60     /**
61      * The same as {@link Collections#binarySearch(List, Object)}
62      * except that the list is a {@link ReadOnlyList}.
63      *
64      * @return the insertion point defined
65      *         in {@link Collections#binarySearch(List, Object)}.
66      */
binarySearch( final ReadOnlyList<E> list, final K key)67     public static <K, E extends Comparable<K>> int binarySearch(
68         final ReadOnlyList<E> list, final K key) {
69       int lower = 0;
70       for(int upper = list.size() - 1; lower <= upper; ) {
71         final int mid = (upper + lower) >>> 1;
72 
73         final int d = list.get(mid).compareTo(key);
74         if (d == 0) {
75           return mid;
76         } else if (d > 0) {
77           upper = mid - 1;
78         } else {
79           lower = mid + 1;
80         }
81       }
82       return -(lower + 1);
83     }
84 
85     /**
86      * @return a {@link ReadOnlyList} view of the given list.
87      */
asReadOnlyList(final List<E> list)88     public static <E> ReadOnlyList<E> asReadOnlyList(final List<E> list) {
89       return new ReadOnlyList<E>() {
90         @Override
91         public Iterator<E> iterator() {
92           return list.iterator();
93         }
94 
95         @Override
96         public boolean isEmpty() {
97           return list.isEmpty();
98         }
99 
100         @Override
101         public int size() {
102           return list.size();
103         }
104 
105         @Override
106         public E get(int i) {
107           return list.get(i);
108         }
109       };
110     }
111 
112     /**
113      * @return a {@link List} view of the given list.
114      */
asList(final ReadOnlyList<E> list)115     public static <E> List<E> asList(final ReadOnlyList<E> list) {
116       return new List<E>() {
117         @Override
118         public Iterator<E> iterator() {
119           return list.iterator();
120         }
121 
122         @Override
123         public boolean isEmpty() {
124           return list.isEmpty();
125         }
126 
127         @Override
128         public int size() {
129           return list.size();
130         }
131 
132         @Override
133         public E get(int i) {
134           return list.get(i);
135         }
136 
137         @Override
138         public Object[] toArray() {
139           final Object[] a = new Object[size()];
140           for(int i = 0; i < a.length; i++) {
141             a[i] = get(i);
142           }
143           return a;
144         }
145 
146         //All methods below are not supported.
147 
148         @Override
149         public boolean add(E e) {
150           throw new UnsupportedOperationException();
151         }
152 
153         @Override
154         public void add(int index, E element) {
155           throw new UnsupportedOperationException();
156         }
157 
158         @Override
159         public boolean addAll(Collection<? extends E> c) {
160           throw new UnsupportedOperationException();
161         }
162 
163         @Override
164         public boolean addAll(int index, Collection<? extends E> c) {
165           throw new UnsupportedOperationException();
166         }
167 
168         @Override
169         public void clear() {
170           throw new UnsupportedOperationException();
171         }
172 
173         @Override
174         public boolean contains(Object o) {
175           throw new UnsupportedOperationException();
176         }
177 
178         @Override
179         public boolean containsAll(Collection<?> c) {
180           throw new UnsupportedOperationException();
181         }
182 
183         @Override
184         public int indexOf(Object o) {
185           throw new UnsupportedOperationException();
186         }
187 
188         @Override
189         public int lastIndexOf(Object o) {
190           throw new UnsupportedOperationException();
191         }
192 
193         @Override
194         public ListIterator<E> listIterator() {
195           throw new UnsupportedOperationException();
196         }
197 
198         @Override
199         public ListIterator<E> listIterator(int index) {
200           throw new UnsupportedOperationException();
201         }
202 
203         @Override
204         public boolean remove(Object o) {
205           throw new UnsupportedOperationException();
206         }
207 
208         @Override
209         public E remove(int index) {
210           throw new UnsupportedOperationException();
211         }
212 
213         @Override
214         public boolean removeAll(Collection<?> c) {
215           throw new UnsupportedOperationException();
216         }
217 
218         @Override
219         public boolean retainAll(Collection<?> c) {
220           throw new UnsupportedOperationException();
221         }
222 
223         @Override
224         public E set(int index, E element) {
225           throw new UnsupportedOperationException();
226         }
227 
228         @Override
229         public List<E> subList(int fromIndex, int toIndex) {
230           throw new UnsupportedOperationException();
231         }
232 
233         @Override
234         public <T> T[] toArray(T[] a) {
235           throw new UnsupportedOperationException();
236         }
237       };
238     }
239   }
240 }
241