1   /**
2    * Copyright 2009 The Apache Software Foundation
3    *
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *     http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing, software
15   * distributed under the License is distributed on an "AS IS" BASIS,
16   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17   * See the License for the specific language governing permissions and
18   * limitations under the License.
19   */
20  package org.apache.hadoop.hbase.regionserver;
21  
22  import java.util.Iterator;
23  import java.util.SortedSet;
24  
25  import org.apache.hadoop.hbase.KeyValue;
26  import org.apache.hadoop.hbase.SmallTests;
27  import org.apache.hadoop.hbase.util.Bytes;
28  
29  import junit.framework.TestCase;
30  import org.junit.experimental.categories.Category;
31  
32  @Category(SmallTests.class)
33  public class TestKeyValueSkipListSet extends TestCase {
34    private final KeyValueSkipListSet kvsls =
35      new KeyValueSkipListSet(KeyValue.COMPARATOR);
36  
37    protected void setUp() throws Exception {
38      super.setUp();
39      this.kvsls.clear();
40    }
41  
42    public void testAdd() throws Exception {
43      byte [] bytes = Bytes.toBytes(getName());
44      KeyValue kv = new KeyValue(bytes, bytes, bytes, bytes);
45      this.kvsls.add(kv);
46      assertTrue(this.kvsls.contains(kv));
47      assertEquals(1, this.kvsls.size());
48      KeyValue first = this.kvsls.first();
49      assertTrue(kv.equals(first));
50      assertTrue(Bytes.equals(kv.getValue(), first.getValue()));
51      // Now try overwritting
52      byte [] overwriteValue = Bytes.toBytes("overwrite");
53      KeyValue overwrite = new KeyValue(bytes, bytes, bytes, overwriteValue);
54      this.kvsls.add(overwrite);
55      assertEquals(1, this.kvsls.size());
56      first = this.kvsls.first();
57      assertTrue(Bytes.equals(overwrite.getValue(), first.getValue()));
58      assertFalse(Bytes.equals(overwrite.getValue(), kv.getValue()));
59    }
60  
61    public void testIterator() throws Exception {
62      byte [] bytes = Bytes.toBytes(getName());
63      byte [] value1 = Bytes.toBytes("1");
64      byte [] value2 = Bytes.toBytes("2");
65      final int total = 3;
66      for (int i = 0; i < total; i++) {
67        this.kvsls.add(new KeyValue(bytes, bytes, Bytes.toBytes("" + i), value1));
68      }
69      // Assert that we added 'total' values and that they are in order
70      int count = 0;
71      for (KeyValue kv: this.kvsls) {
72        assertEquals("" + count, Bytes.toString(kv.getQualifier()));
73        assertTrue(Bytes.equals(kv.getValue(), value1));
74        count++;
75      }
76      assertEquals(total, count);
77      // Now overwrite with a new value.
78      for (int i = 0; i < total; i++) {
79        this.kvsls.add(new KeyValue(bytes, bytes, Bytes.toBytes("" + i), value2));
80      }
81      // Assert that we added 'total' values and that they are in order and that
82      // we are getting back value2
83      count = 0;
84      for (KeyValue kv: this.kvsls) {
85        assertEquals("" + count, Bytes.toString(kv.getQualifier()));
86        assertTrue(Bytes.equals(kv.getValue(), value2));
87        count++;
88      }
89      assertEquals(total, count);
90    }
91  
92    public void testDescendingIterator() throws Exception {
93      byte [] bytes = Bytes.toBytes(getName());
94      byte [] value1 = Bytes.toBytes("1");
95      byte [] value2 = Bytes.toBytes("2");
96      final int total = 3;
97      for (int i = 0; i < total; i++) {
98        this.kvsls.add(new KeyValue(bytes, bytes, Bytes.toBytes("" + i), value1));
99      }
100     // Assert that we added 'total' values and that they are in order
101     int count = 0;
102     for (Iterator<KeyValue> i = this.kvsls.descendingIterator(); i.hasNext();) {
103       KeyValue kv = i.next();
104       assertEquals("" + (total - (count + 1)), Bytes.toString(kv.getQualifier()));
105       assertTrue(Bytes.equals(kv.getValue(), value1));
106       count++;
107     }
108     assertEquals(total, count);
109     // Now overwrite with a new value.
110     for (int i = 0; i < total; i++) {
111       this.kvsls.add(new KeyValue(bytes, bytes, Bytes.toBytes("" + i), value2));
112     }
113     // Assert that we added 'total' values and that they are in order and that
114     // we are getting back value2
115     count = 0;
116     for (Iterator<KeyValue> i = this.kvsls.descendingIterator(); i.hasNext();) {
117       KeyValue kv = i.next();
118       assertEquals("" + (total - (count + 1)), Bytes.toString(kv.getQualifier()));
119       assertTrue(Bytes.equals(kv.getValue(), value2));
120       count++;
121     }
122     assertEquals(total, count);
123   }
124 
125   public void testHeadTail() throws Exception {
126     byte [] bytes = Bytes.toBytes(getName());
127     byte [] value1 = Bytes.toBytes("1");
128     byte [] value2 = Bytes.toBytes("2");
129     final int total = 3;
130     KeyValue splitter = null;
131     for (int i = 0; i < total; i++) {
132       KeyValue kv = new KeyValue(bytes, bytes, Bytes.toBytes("" + i), value1);
133       if (i == 1) splitter = kv;
134       this.kvsls.add(kv);
135     }
136     SortedSet<KeyValue> tail = this.kvsls.tailSet(splitter);
137     assertEquals(2, tail.size());
138     SortedSet<KeyValue> head = this.kvsls.headSet(splitter);
139     assertEquals(1, head.size());
140     // Now ensure that we get back right answer even when we do tail or head.
141     // Now overwrite with a new value.
142     for (int i = 0; i < total; i++) {
143       this.kvsls.add(new KeyValue(bytes, bytes, Bytes.toBytes("" + i), value2));
144     }
145     tail = this.kvsls.tailSet(splitter);
146     assertTrue(Bytes.equals(tail.first().getValue(), value2));
147     head = this.kvsls.headSet(splitter);
148     assertTrue(Bytes.equals(head.first().getValue(), value2));
149   }
150 
151   @org.junit.Rule
152   public org.apache.hadoop.hbase.ResourceCheckerJUnitRule cu =
153     new org.apache.hadoop.hbase.ResourceCheckerJUnitRule();
154 }
155