HBASE-10079 Race in TableName cache

git-svn-id: https://svn.apache.org/repos/asf/hbase/trunk@1548020 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Jonathan Hsieh 2013-12-05 06:16:30 +00:00
parent 5fbbef29f3
commit 3fb88f10af
2 changed files with 15 additions and 16 deletions

View File

@ -248,7 +248,7 @@ public final class TableName implements Comparable<TableName> {
*/ */
private TableName(ByteBuffer namespace, ByteBuffer qualifier) throws IllegalArgumentException { private TableName(ByteBuffer namespace, ByteBuffer qualifier) throws IllegalArgumentException {
this.qualifier = new byte[qualifier.remaining()]; this.qualifier = new byte[qualifier.remaining()];
qualifier.get(this.qualifier); qualifier.duplicate().get(this.qualifier);
this.qualifierAsString = Bytes.toString(this.qualifier); this.qualifierAsString = Bytes.toString(this.qualifier);
if (qualifierAsString.equals(OLD_ROOT_STR)) { if (qualifierAsString.equals(OLD_ROOT_STR)) {
@ -275,7 +275,7 @@ public final class TableName implements Comparable<TableName> {
this.systemTable = true; this.systemTable = true;
} else { } else {
this.namespace = new byte[namespace.remaining()]; this.namespace = new byte[namespace.remaining()];
namespace.get(this.namespace); namespace.duplicate().get(this.namespace);
this.namespaceAsString = Bytes.toString(this.namespace); this.namespaceAsString = Bytes.toString(this.namespace);
this.systemTable = false; this.systemTable = false;
} }
@ -325,15 +325,15 @@ public final class TableName implements Comparable<TableName> {
TableName newTable = new TableName(bns, qns); TableName newTable = new TableName(bns, qns);
if (tableCache.add(newTable)) { // Adds the specified element if it is not already present if (tableCache.add(newTable)) { // Adds the specified element if it is not already present
return newTable; return newTable;
} else {
// Someone else added it. Let's find it.
for (TableName tn : tableCache) {
if (Bytes.equals(tn.getQualifier(), qns) && Bytes.equals(tn.getNamespace(), bns)) {
return tn;
}
}
} }
// Someone else added it. Let's find it.
for (TableName tn : tableCache) {
if (Bytes.equals(tn.getQualifier(), qns) && Bytes.equals(tn.getNamespace(), bns)) {
return tn;
}
}
// this should never happen.
throw new IllegalStateException(newTable + " was supposed to be in the cache"); throw new IllegalStateException(newTable + " was supposed to be in the cache");
} }

View File

@ -1279,19 +1279,18 @@ public class Bytes {
* @param b right operand * @param b right operand
* @return True if equal * @return True if equal
*/ */
public static boolean equals(byte[] a, ByteBuffer b) { public static boolean equals(byte[] a, ByteBuffer buf) {
if (a == null) return b == null; if (a == null) return buf == null;
if (b == null) return false; if (buf == null) return false;
if (a.length != b.remaining()) return false; if (a.length != buf.remaining()) return false;
b.mark(); // Thou shalt not modify the original byte buffer in what should be read only operations.
ByteBuffer b = buf.duplicate();
for (byte anA : a) { for (byte anA : a) {
if (anA != b.get()) { if (anA != b.get()) {
b.reset();
return false; return false;
} }
} }
b.reset();
return true; return true;
} }