diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/MemStoreFlusher.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/MemStoreFlusher.java index f839e05..ce60aba 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/MemStoreFlusher.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/MemStoreFlusher.java @@ -590,7 +590,8 @@ class MemStoreFlusher implements FlushRequester { return queueList.toString(); } - interface FlushQueueEntry extends Delayed {} + interface FlushQueueEntry extends Delayed { + } /** * Token to insert into the flush queue that ensures that the flusher does not sleep @@ -610,7 +611,6 @@ class MemStoreFlusher implements FlushRequester { public boolean equals(Object obj) { return (this == obj); } - } /** @@ -670,8 +670,14 @@ class MemStoreFlusher implements FlushRequester { @Override public int compareTo(Delayed other) { - return Long.valueOf(getDelay(TimeUnit.MILLISECONDS) - + // Delay is compared first. If there is a tie, compare region's hash code + int ret = Long.valueOf(getDelay(TimeUnit.MILLISECONDS) - other.getDelay(TimeUnit.MILLISECONDS)).intValue(); + if (ret != 0) { + return ret; + } + FlushQueueEntry otherEntry = (FlushQueueEntry) other; + return hashCode() - otherEntry.hashCode(); } @Override @@ -680,6 +686,12 @@ class MemStoreFlusher implements FlushRequester { } @Override + public int hashCode() { + int hash = (int) getDelay(TimeUnit.MILLISECONDS); + return hash ^ region.hashCode(); + } + + @Override public boolean equals(Object obj) { if (this == obj) { return true; diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestFlushRegionEntry.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestFlushRegionEntry.java new file mode 100644 index 0000000..470ff60 --- /dev/null +++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestFlushRegionEntry.java @@ -0,0 +1,48 @@ +/** + * 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 static org.junit.Assert.*; + +import org.apache.hadoop.hbase.testclassification.SmallTests; +import org.apache.hadoop.hbase.regionserver.MemStoreFlusher.FlushRegionEntry; +import org.apache.hadoop.hbase.util.EnvironmentEdgeManager; +import org.apache.hadoop.hbase.util.ManualEnvironmentEdge; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.experimental.categories.Category; +import org.mockito.Mockito; + +@Category(SmallTests.class) +public class TestFlushRegionEntry { + @Before + public void setUp() throws Exception { + ManualEnvironmentEdge edge = new ManualEnvironmentEdge(); + edge.setValue(12345); + EnvironmentEdgeManager.injectEdge(edge); + } + + @Test + public void test() { + HRegion r = Mockito.mock(HRegion.class); + FlushRegionEntry entry = new FlushRegionEntry(r); + FlushRegionEntry other = new FlushRegionEntry(r); + + assertEquals(entry.hashCode(), other.hashCode()); + assertEquals(entry, other); + } + + @After + public void teardown() { + EnvironmentEdgeManager.reset(); + } +}