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.hdfs.util;
019
020import java.util.Collection;
021import java.util.Collections;
022import java.util.Iterator;
023import java.util.List;
024import java.util.ListIterator;
025
026import org.apache.hadoop.classification.InterfaceAudience;
027
028/**
029 * A {@link ReadOnlyList} is a unmodifiable list,
030 * which supports read-only operations.
031 * 
032 * @param <E> The type of the list elements.
033 */
034@InterfaceAudience.Private
035public interface ReadOnlyList<E> extends Iterable<E> {
036  /**
037   * Is this an empty list?
038   */
039  boolean isEmpty();
040
041  /**
042   * @return the size of this list.
043   */
044  int size();
045
046  /**
047   * @return the i-th element.
048   */
049  E get(int i);
050  
051  /**
052   * Utilities for {@link ReadOnlyList}
053   */
054  public static class Util {
055    /** @return an empty list. */
056    public static <E> ReadOnlyList<E> emptyList() {
057      return ReadOnlyList.Util.asReadOnlyList(Collections.<E>emptyList());
058    }
059
060    /**
061     * The same as {@link Collections#binarySearch(List, Object)}
062     * except that the list is a {@link ReadOnlyList}.
063     *
064     * @return the insertion point defined
065     *         in {@link Collections#binarySearch(List, Object)}.
066     */
067    public static <K, E extends Comparable<K>> int binarySearch(
068        final ReadOnlyList<E> list, final K key) {
069      int lower = 0;
070      for(int upper = list.size() - 1; lower <= upper; ) {
071        final int mid = (upper + lower) >>> 1;
072
073        final int d = list.get(mid).compareTo(key);
074        if (d == 0) {
075          return mid;
076        } else if (d > 0) {
077          upper = mid - 1;
078        } else {
079          lower = mid + 1;
080        }
081      }
082      return -(lower + 1);
083    }
084
085    /**
086     * @return a {@link ReadOnlyList} view of the given list.
087     */
088    public static <E> ReadOnlyList<E> asReadOnlyList(final List<E> list) {
089      return new ReadOnlyList<E>() {
090        @Override
091        public Iterator<E> iterator() {
092          return list.iterator();
093        }
094
095        @Override
096        public boolean isEmpty() {
097          return list.isEmpty();
098        }
099
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     */
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}