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 static org.junit.Assert.assertEquals;
021import static org.junit.Assert.assertFalse;
022import static org.junit.Assert.assertTrue;
023
024import java.util.Iterator;
025import java.util.SortedSet;
026import org.apache.hadoop.hbase.Cell;
027import org.apache.hadoop.hbase.CellComparatorImpl;
028import org.apache.hadoop.hbase.CellUtil;
029import org.apache.hadoop.hbase.HBaseClassTestRule;
030import org.apache.hadoop.hbase.KeyValue;
031import org.apache.hadoop.hbase.testclassification.RegionServerTests;
032import org.apache.hadoop.hbase.testclassification.SmallTests;
033import org.apache.hadoop.hbase.util.Bytes;
034import org.junit.Before;
035import org.junit.ClassRule;
036import org.junit.Rule;
037import org.junit.Test;
038import org.junit.experimental.categories.Category;
039import org.junit.rules.TestName;
040
041@Category({ RegionServerTests.class, SmallTests.class })
042public class TestCellSkipListSet {
043
044  @ClassRule
045  public static final HBaseClassTestRule CLASS_RULE =
046    HBaseClassTestRule.forClass(TestCellSkipListSet.class);
047
048  private final CellSet csls = new CellSet(CellComparatorImpl.COMPARATOR);
049
050  @Rule
051  public TestName name = new TestName();
052
053  @Before
054  public void setUp() throws Exception {
055    this.csls.clear();
056  }
057
058  @Test
059  public void testAdd() throws Exception {
060    byte[] bytes = Bytes.toBytes(name.getMethodName());
061    KeyValue kv = new KeyValue(bytes, bytes, bytes, bytes);
062    this.csls.add(kv);
063    assertTrue(this.csls.contains(kv));
064    assertEquals(1, this.csls.getDelegatee().size());
065    Cell first = this.csls.first();
066    assertTrue(kv.equals(first));
067    assertTrue(Bytes.equals(kv.getValueArray(), kv.getValueOffset(), kv.getValueLength(),
068      first.getValueArray(), first.getValueOffset(), first.getValueLength()));
069    // Now try overwritting
070    byte[] overwriteValue = Bytes.toBytes("overwrite");
071    KeyValue overwrite = new KeyValue(bytes, bytes, bytes, overwriteValue);
072    this.csls.add(overwrite);
073    assertEquals(1, this.csls.getDelegatee().size());
074    first = this.csls.first();
075    assertTrue(Bytes.equals(overwrite.getValueArray(), overwrite.getValueOffset(),
076      overwrite.getValueLength(), first.getValueArray(), first.getValueOffset(),
077      first.getValueLength()));
078    assertFalse(Bytes.equals(CellUtil.cloneValue(overwrite), CellUtil.cloneValue(kv)));
079  }
080
081  @Test
082  public void testIterator() throws Exception {
083    byte[] bytes = Bytes.toBytes(name.getMethodName());
084    byte[] value1 = Bytes.toBytes("1");
085    byte[] value2 = Bytes.toBytes("2");
086    final int total = 3;
087    for (int i = 0; i < total; i++) {
088      this.csls.add(new KeyValue(bytes, bytes, Bytes.toBytes("" + i), value1));
089    }
090    // Assert that we added 'total' values and that they are in order
091    int count = 0;
092    for (Cell kv : this.csls) {
093      assertEquals("" + count,
094        Bytes.toString(kv.getQualifierArray(), kv.getQualifierOffset(), kv.getQualifierLength()));
095      assertTrue(Bytes.equals(kv.getValueArray(), kv.getValueOffset(), kv.getValueLength(), value1,
096        0, value1.length));
097      count++;
098    }
099    assertEquals(total, count);
100    // Now overwrite with a new value.
101    for (int i = 0; i < total; i++) {
102      this.csls.add(new KeyValue(bytes, bytes, Bytes.toBytes("" + i), value2));
103    }
104    // Assert that we added 'total' values and that they are in order and that
105    // we are getting back value2
106    count = 0;
107    for (Cell kv : this.csls) {
108      assertEquals("" + count,
109        Bytes.toString(kv.getQualifierArray(), kv.getQualifierOffset(), kv.getQualifierLength()));
110      assertTrue(Bytes.equals(kv.getValueArray(), kv.getValueOffset(), kv.getValueLength(), value2,
111        0, value2.length));
112      count++;
113    }
114    assertEquals(total, count);
115  }
116
117  @Test
118  public void testDescendingIterator() throws Exception {
119    byte[] bytes = Bytes.toBytes(name.getMethodName());
120    byte[] value1 = Bytes.toBytes("1");
121    byte[] value2 = Bytes.toBytes("2");
122    final int total = 3;
123    for (int i = 0; i < total; i++) {
124      this.csls.add(new KeyValue(bytes, bytes, Bytes.toBytes("" + i), value1));
125    }
126    // Assert that we added 'total' values and that they are in order
127    int count = 0;
128    for (Iterator<Cell> i = this.csls.descendingIterator(); i.hasNext();) {
129      Cell kv = i.next();
130      assertEquals("" + (total - (count + 1)),
131        Bytes.toString(kv.getQualifierArray(), kv.getQualifierOffset(), kv.getQualifierLength()));
132      assertTrue(Bytes.equals(kv.getValueArray(), kv.getValueOffset(), kv.getValueLength(), value1,
133        0, value1.length));
134      count++;
135    }
136    assertEquals(total, count);
137    // Now overwrite with a new value.
138    for (int i = 0; i < total; i++) {
139      this.csls.add(new KeyValue(bytes, bytes, Bytes.toBytes("" + i), value2));
140    }
141    // Assert that we added 'total' values and that they are in order and that
142    // we are getting back value2
143    count = 0;
144    for (Iterator<Cell> i = this.csls.descendingIterator(); i.hasNext();) {
145      Cell kv = i.next();
146      assertEquals("" + (total - (count + 1)),
147        Bytes.toString(kv.getQualifierArray(), kv.getQualifierOffset(), kv.getQualifierLength()));
148      assertTrue(Bytes.equals(kv.getValueArray(), kv.getValueOffset(), kv.getValueLength(), value2,
149        0, value2.length));
150      count++;
151    }
152    assertEquals(total, count);
153  }
154
155  @Test
156  public void testHeadTail() throws Exception {
157    byte[] bytes = Bytes.toBytes(name.getMethodName());
158    byte[] value1 = Bytes.toBytes("1");
159    byte[] value2 = Bytes.toBytes("2");
160    final int total = 3;
161    KeyValue splitter = null;
162    for (int i = 0; i < total; i++) {
163      KeyValue kv = new KeyValue(bytes, bytes, Bytes.toBytes("" + i), value1);
164      if (i == 1) splitter = kv;
165      this.csls.add(kv);
166    }
167    SortedSet<Cell> tail = this.csls.tailSet(splitter);
168    assertEquals(2, tail.size());
169    SortedSet<Cell> head = this.csls.headSet(splitter);
170    assertEquals(1, head.size());
171    // Now ensure that we get back right answer even when we do tail or head.
172    // Now overwrite with a new value.
173    for (int i = 0; i < total; i++) {
174      this.csls.add(new KeyValue(bytes, bytes, Bytes.toBytes("" + i), value2));
175    }
176    tail = this.csls.tailSet(splitter);
177    assertTrue(Bytes.equals(tail.first().getValueArray(), tail.first().getValueOffset(),
178      tail.first().getValueLength(), value2, 0, value2.length));
179    head = this.csls.headSet(splitter);
180    assertTrue(Bytes.equals(head.first().getValueArray(), head.first().getValueOffset(),
181      head.first().getValueLength(), value2, 0, value2.length));
182  }
183}