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.util;
019
020import static org.junit.jupiter.api.Assertions.assertEquals;
021import static org.junit.jupiter.api.Assertions.assertFalse;
022import static org.junit.jupiter.api.Assertions.assertThrows;
023import static org.junit.jupiter.api.Assertions.assertTrue;
024
025import java.util.ArrayList;
026import java.util.Arrays;
027import java.util.Iterator;
028import java.util.List;
029import java.util.NoSuchElementException;
030import org.apache.hadoop.hbase.testclassification.MiscTests;
031import org.apache.hadoop.hbase.testclassification.SmallTests;
032import org.junit.jupiter.api.Tag;
033import org.junit.jupiter.api.Test;
034
035@Tag(MiscTests.TAG)
036@Tag(SmallTests.TAG)
037public class TestConcatenatedLists {
038
039  @Test
040  public void testUnsupportedOps() {
041    // If adding support, add tests.
042    ConcatenatedLists<Long> c = new ConcatenatedLists<>();
043    c.addSublist(Arrays.asList(0L, 1L));
044    assertThrows(UnsupportedOperationException.class, () -> c.add(2L));
045    assertThrows(UnsupportedOperationException.class, () -> c.addAll(Arrays.asList(2L, 3L)));
046    assertThrows(UnsupportedOperationException.class, () -> c.remove(0L));
047    assertThrows(UnsupportedOperationException.class, () -> c.removeAll(Arrays.asList(0L, 1L)));
048    assertThrows(UnsupportedOperationException.class, () -> c.clear());
049    assertThrows(UnsupportedOperationException.class, () -> c.retainAll(Arrays.asList(0L, 2L)));
050
051    Iterator<Long> iter = c.iterator();
052    iter.next();
053    assertThrows(UnsupportedOperationException.class, () -> iter.remove());
054  }
055
056  @Test
057  public void testEmpty() {
058    verify(new ConcatenatedLists<>(), -1);
059  }
060
061  @Test
062  public void testOneOne() {
063    ConcatenatedLists<Long> c = new ConcatenatedLists<>();
064    c.addSublist(Arrays.asList(0L));
065    verify(c, 0);
066  }
067
068  @Test
069  public void testOneMany() {
070    ConcatenatedLists<Long> c = new ConcatenatedLists<>();
071    c.addSublist(Arrays.asList(0L, 1L, 2L));
072    verify(c, 2);
073  }
074
075  @Test
076  public void testManyOne() {
077    ConcatenatedLists<Long> c = new ConcatenatedLists<>();
078    c.addSublist(Arrays.asList(0L));
079    c.addAllSublists(Arrays.asList(Arrays.asList(1L), Arrays.asList(2L)));
080    verify(c, 2);
081  }
082
083  @Test
084  public void testManyMany() {
085    ConcatenatedLists<Long> c = new ConcatenatedLists<>();
086    c.addAllSublists(Arrays.asList(Arrays.asList(0L, 1L)));
087    c.addSublist(Arrays.asList(2L, 3L, 4L));
088    c.addAllSublists(Arrays.asList(Arrays.asList(5L), Arrays.asList(6L, 7L)));
089    verify(c, 7);
090  }
091
092  @SuppressWarnings("ModifyingCollectionWithItself")
093  @edu.umd.cs.findbugs.annotations.SuppressWarnings(value = "DMI_VACUOUS_SELF_COLLECTION_CALL",
094      justification = "Intended vacuous containsAll call on 'c'")
095  private void verify(ConcatenatedLists<Long> c, int last) {
096    assertEquals((last == -1), c.isEmpty());
097    assertEquals(last + 1, c.size());
098    // This check is O(n^2), test with care
099    assertTrue(c.containsAll(c));
100    Long[] array = c.toArray(new Long[c.size()]);
101    List<Long> all = new ArrayList<>();
102    Iterator<Long> iter = c.iterator();
103    for (Long i = 0L; i <= last; ++i) {
104      assertTrue(iter.hasNext());
105      assertEquals(i, iter.next());
106      assertEquals(i, array[i.intValue()]);
107      assertTrue(c.contains(i));
108      assertTrue(c.containsAll(Arrays.asList(i)));
109      all.add(i);
110    }
111    assertTrue(c.containsAll(all));
112    assertFalse(iter.hasNext());
113    assertThrows(NoSuchElementException.class, () -> iter.next());
114  }
115}