blob: dc2743f5d52387c80d5767c9ac263dc4e7bc9a72 [file] [log] [blame]
/*
* Copyright 2010 The Apache Software Foundation
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.hadoop.hbase.regionserver;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
/**
* Test class for the priority compaction queue
*/
public class TestPriorityCompactionQueue {
static final Log LOG = LogFactory.getLog(TestPriorityCompactionQueue.class);
@Before
public void setUp() {
}
@After
public void tearDown() {
}
class DummyHRegion extends HRegion {
String name;
DummyHRegion(String name) {
super();
this.name = name;
}
public int hashCode() {
return name.hashCode();
}
public boolean equals(DummyHRegion r) {
return name.equals(r.name);
}
public String toString() {
return "[DummyHRegion " + name + "]";
}
public String getRegionNameAsString() {
return name;
}
}
protected void getAndCheckRegion(PriorityCompactionQueue pq,
HRegion checkRegion) {
HRegion r = pq.remove();
if (r != checkRegion) {
Assert.assertTrue("Didn't get expected " + checkRegion + " got " + r, r
.equals(checkRegion));
}
}
protected void addRegion(PriorityCompactionQueue pq, HRegion r, int p) {
pq.add(r, p);
try {
// Sleep 1 millisecond so 2 things are not put in the queue within the
// same millisecond. The queue breaks ties arbitrarily between two
// requests inserted at the same time. We want the ordering to
// be consistent for our unit test.
Thread.sleep(1);
} catch (InterruptedException ex) {
// continue
}
}
// ////////////////////////////////////////////////////////////////////////////
// tests
// ////////////////////////////////////////////////////////////////////////////
/** tests general functionality of the compaction queue */
@Test public void testPriorityQueue() throws InterruptedException {
PriorityCompactionQueue pq = new PriorityCompactionQueue();
HRegion r1 = new DummyHRegion("r1");
HRegion r2 = new DummyHRegion("r2");
HRegion r3 = new DummyHRegion("r3");
HRegion r4 = new DummyHRegion("r4");
HRegion r5 = new DummyHRegion("r5");
// test 1
// check fifo w/priority
addRegion(pq, r1, 0);
addRegion(pq, r2, 0);
addRegion(pq, r3, 0);
addRegion(pq, r4, 0);
addRegion(pq, r5, 0);
getAndCheckRegion(pq, r1);
getAndCheckRegion(pq, r2);
getAndCheckRegion(pq, r3);
getAndCheckRegion(pq, r4);
getAndCheckRegion(pq, r5);
// test 2
// check fifo w/mixed priority
addRegion(pq, r1, 0);
addRegion(pq, r2, CompactSplitThread.PRIORITY_USER);
addRegion(pq, r3, 0);
addRegion(pq, r4, CompactSplitThread.PRIORITY_USER);
addRegion(pq, r5, 0);
getAndCheckRegion(pq, r1);
getAndCheckRegion(pq, r3);
getAndCheckRegion(pq, r5);
getAndCheckRegion(pq, r2);
getAndCheckRegion(pq, r4);
// test 3
// check fifo w/mixed priority
addRegion(pq, r1, CompactSplitThread.PRIORITY_USER);
addRegion(pq, r2, CompactSplitThread.PRIORITY_USER);
addRegion(pq, r3, CompactSplitThread.PRIORITY_USER);
addRegion(pq, r4, CompactSplitThread.PRIORITY_USER);
addRegion(pq, r5, 0);
getAndCheckRegion(pq, r5);
getAndCheckRegion(pq, r1);
getAndCheckRegion(pq, r2);
getAndCheckRegion(pq, r3);
getAndCheckRegion(pq, r4);
// test 4
// check fifo w/mixed priority elevation time
addRegion(pq, r1, CompactSplitThread.PRIORITY_USER);
addRegion(pq, r2, 0);
addRegion(pq, r3, CompactSplitThread.PRIORITY_USER);
Thread.sleep(1000);
addRegion(pq, r4, CompactSplitThread.PRIORITY_USER);
addRegion(pq, r5, 0);
getAndCheckRegion(pq, r2);
getAndCheckRegion(pq, r5);
getAndCheckRegion(pq, r1);
getAndCheckRegion(pq, r3);
getAndCheckRegion(pq, r4);
// reset the priority compaction queue back to a normal queue
pq = new PriorityCompactionQueue();
// test 5
// test that lower priority are removed from the queue when a high priority
// is added
addRegion(pq, r1, CompactSplitThread.PRIORITY_USER);
addRegion(pq, r2, CompactSplitThread.PRIORITY_USER);
addRegion(pq, r3, CompactSplitThread.PRIORITY_USER);
addRegion(pq, r4, CompactSplitThread.PRIORITY_USER);
addRegion(pq, r5, CompactSplitThread.PRIORITY_USER);
addRegion(pq, r3, 0);
getAndCheckRegion(pq, r3);
getAndCheckRegion(pq, r1);
getAndCheckRegion(pq, r2);
getAndCheckRegion(pq, r4);
getAndCheckRegion(pq, r5);
Assert.assertTrue("Queue should be empty.", pq.size() == 0);
// test 6
// don't add the same region more than once
addRegion(pq, r1, CompactSplitThread.PRIORITY_USER);
addRegion(pq, r2, CompactSplitThread.PRIORITY_USER);
addRegion(pq, r3, CompactSplitThread.PRIORITY_USER);
addRegion(pq, r4, CompactSplitThread.PRIORITY_USER);
addRegion(pq, r5, CompactSplitThread.PRIORITY_USER);
addRegion(pq, r1, CompactSplitThread.PRIORITY_USER);
addRegion(pq, r2, CompactSplitThread.PRIORITY_USER);
addRegion(pq, r3, CompactSplitThread.PRIORITY_USER);
addRegion(pq, r4, CompactSplitThread.PRIORITY_USER);
addRegion(pq, r5, CompactSplitThread.PRIORITY_USER);
getAndCheckRegion(pq, r1);
getAndCheckRegion(pq, r2);
getAndCheckRegion(pq, r3);
getAndCheckRegion(pq, r4);
getAndCheckRegion(pq, r5);
Assert.assertTrue("Queue should be empty.", pq.size() == 0);
// test 7
// we can handle negative priorities
addRegion(pq, r1, CompactSplitThread.PRIORITY_USER);
addRegion(pq, r2, -1);
addRegion(pq, r3, 0);
addRegion(pq, r4, -2);
getAndCheckRegion(pq, r4);
getAndCheckRegion(pq, r2);
getAndCheckRegion(pq, r3);
getAndCheckRegion(pq, r1);
Assert.assertTrue("Queue should be empty.", pq.size() == 0);
}
}