From 6d2ccec8351c033717f9212b6922d973dfb4c2df Mon Sep 17 00:00:00 2001 From: Alex Newman Date: Wed, 11 Jan 2012 14:09:42 -0800 Subject: [PATCH] HBASE-2600. Change how we do meta tables; from tablename+STARTROW+randomid to instead, tablename+ENDROW+randomid --- .../java/org/apache/hadoop/hbase/HConstants.java | 8 +- .../java/org/apache/hadoop/hbase/HRegionInfo.java | 305 ++++++++++++-------- .../org/apache/hadoop/hbase/HTableDescriptor.java | 66 ++++- .../java/org/apache/hadoop/hbase/KeyValue.java | 2 +- .../apache/hadoop/hbase/catalog/MetaReader.java | 33 +-- .../org/apache/hadoop/hbase/client/HBaseAdmin.java | 4 +- .../hadoop/hbase/client/HConnectionManager.java | 144 +++++++--- .../apache/hadoop/hbase/client/MetaScanner.java | 45 +-- .../apache/hadoop/hbase/rest/RegionsResource.java | 17 +- .../hadoop/hbase/rest/model/TableRegionModel.java | 35 ++- .../java/org/apache/hadoop/hbase/TestKeyValue.java | 10 +- .../regionserver/TestGetClosestAtOrBefore.java | 84 +------ .../hadoop/hbase/regionserver/TestHRegionInfo.java | 13 +- .../hadoop/hbase/rest/TestStatusResource.java | 17 +- .../hbase/rest/model/TestTableRegionModel.java | 28 +- 15 files changed, 454 insertions(+), 357 deletions(-) diff --git src/main/java/org/apache/hadoop/hbase/HConstants.java src/main/java/org/apache/hadoop/hbase/HConstants.java index 5120a3c..93f78f2 100644 --- src/main/java/org/apache/hadoop/hbase/HConstants.java +++ src/main/java/org/apache/hadoop/hbase/HConstants.java @@ -44,7 +44,10 @@ public final class HConstants { /** long constant for zero */ public static final Long ZERO_L = Long.valueOf(0L); + public static final String NINES = "99999999999999"; + + @Deprecated public static final String ZEROES = "00000000000000"; // For migration @@ -236,7 +239,7 @@ public final class HConstants { // Always store the location of the root table's HRegion. // This HRegion is never split. - // region name = table + startkey + regionid. This is the row key. + // region name = table + endkey + regionid. This is the row key. // each row in the root and meta tables describes exactly 1 region // Do we ever need to know all the information that we are storing? @@ -259,9 +262,6 @@ public final class HConstants { /** The META table's name. */ public static final byte [] META_TABLE_NAME = Bytes.toBytes(".META."); - /** delimiter used between portions of a region name */ - public static final int META_ROW_DELIMITER = ','; - /** The catalog family as a string*/ public static final String CATALOG_FAMILY_STR = "info"; diff --git src/main/java/org/apache/hadoop/hbase/HRegionInfo.java src/main/java/org/apache/hadoop/hbase/HRegionInfo.java index 74cb821..336b1c0 100644 --- src/main/java/org/apache/hadoop/hbase/HRegionInfo.java +++ src/main/java/org/apache/hadoop/hbase/HRegionInfo.java @@ -23,6 +23,8 @@ import java.io.DataInput; import java.io.DataOutput; import java.io.EOFException; import java.io.IOException; +import java.nio.ByteBuffer; +import java.nio.MappedByteBuffer; import java.util.Arrays; import org.apache.commons.logging.Log; @@ -31,6 +33,8 @@ import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.FileSystem; import org.apache.hadoop.fs.Path; import org.apache.hadoop.hbase.KeyValue.KVComparator; + + import org.apache.hadoop.hbase.migration.HRegionInfo090x; import org.apache.hadoop.hbase.util.Bytes; import org.apache.hadoop.hbase.util.FSTableDescriptors; @@ -57,13 +61,13 @@ implements WritableComparable { * in the filesystem. * * New region name format: - * <tablename>,,<startkey>,<regionIdTimestamp>.<encodedName>. + * <tablename>,,<endkey>,<regionIdTimestamp>.<encodedName>. * where, * <encodedName> is a hex version of the MD5 hash of - * <tablename>,<startkey>,<regionIdTimestamp> + * <tablename>,<endkey>,<regionIdTimestamp> * * The old region name format: - * <tablename>,<startkey>,<regionIdTimestamp> + * <tablename>,<endkey>,<regionIdTimestamp> * For region names in the old format, the encoded name is a 32-bit * JenkinsHash integer value (in its decimal notation, string form). *

@@ -77,8 +81,8 @@ implements WritableComparable { /** Separator used to demarcate the encodedName in a region name * in the new format. See description on new format above. */ - private static final int ENC_SEPARATOR = '.'; - public static final int MD5_HEX_LENGTH = 32; + public static final int ENC_SEPARATOR = '.'; + public static final int MD5_HEX_LENGTH = 32; /** * Does region name contain its encoded name? @@ -91,7 +95,7 @@ implements WritableComparable { if ((regionName.length >= 1) && (regionName[regionName.length - 1] == ENC_SEPARATOR)) { // region name is new format. it contains the encoded name. - return true; + return true; } return false; } @@ -104,7 +108,7 @@ implements WritableComparable { String encodedName; if (hasEncodedName(regionName)) { // region is in new format: - // ,,/encodedName/ + // ,,/encodedName/ encodedName = Bytes.toString(regionName, regionName.length - MD5_HEX_LENGTH - 1, MD5_HEX_LENGTH); @@ -137,13 +141,19 @@ implements WritableComparable { /** delimiter used between portions of a region name */ public static final int DELIMITER = ','; + // It should say, the tablename encoded in the region ends with !, + // but the last region's tablename ends with " + public static final int END_OF_TABLE_NAME = 33; // The ascii for ! + public static final int END_OF_TABLE_NAME_FOR_EMPTY_ENDKEY = + END_OF_TABLE_NAME + 1; + /** HRegionInfo for root region */ public static final HRegionInfo ROOT_REGIONINFO = - new HRegionInfo(0L, Bytes.toBytes("-ROOT-")); + new HRegionInfo(0L, HConstants.ROOT_TABLE_NAME); /** HRegionInfo for first meta region */ public static final HRegionInfo FIRST_META_REGIONINFO = - new HRegionInfo(1L, Bytes.toBytes(".META.")); + new HRegionInfo(1L, HConstants.META_TABLE_NAME); private byte [] endKey = HConstants.EMPTY_BYTE_ARRAY; // This flag is in the parent of a split while the parent is still referenced @@ -272,7 +282,11 @@ implements WritableComparable { this.offLine = false; this.regionId = regionid; - this.regionName = createRegionName(this.tableName, startKey, regionId, true); + this.regionName = createRegionName(this.tableName, + startKey, + endKey, + regionId, + true); this.regionNameStr = Bytes.toStringBinary(this.regionName); this.split = split; @@ -283,7 +297,19 @@ implements WritableComparable { setHashCode(); } - /** + private byte[] createRegionName(byte[] tableName, + byte[] startKey, + byte[] endKey, + long regionId, + boolean b) { + return createRegionName(tableName, + startKey, + endKey, + Long.toString(regionId), + b); + } + + /** * Costruct a copy of another HRegionInfo * * @param other @@ -303,35 +329,29 @@ implements WritableComparable { } - /** - * Make a region name of passed parameters. - * @param tableName - * @param startKey Can be null - * @param regionid Region id (Usually timestamp from when region was created). - * @param newFormat should we create the region name in the new format - * (such that it contains its encoded name?). - * @return Region name made of passed tableName, startKey and id - */ - public static byte [] createRegionName(final byte [] tableName, - final byte [] startKey, final long regionid, boolean newFormat) { - return createRegionName(tableName, startKey, Long.toString(regionid), newFormat); - } - - /** - * Make a region name of passed parameters. - * @param tableName - * @param startKey Can be null - * @param id Region id (Usually timestamp from when region was created). - * @param newFormat should we create the region name in the new format - * (such that it contains its encoded name?). - * @return Region name made of passed tableName, startKey and id - */ - public static byte [] createRegionName(final byte [] tableName, - final byte [] startKey, final String id, boolean newFormat) { - return createRegionName(tableName, startKey, Bytes.toBytes(id), newFormat); - } + /** + * Make a region name of passed parameters. + * + * + * @param tableName + * @param regionid Region id (Usually timestamp from when region was + * created). + * @param newFormat should we create the region name in the new format + * (such that it contains its encoded name?). + * @return Region name made of passed tableName, endKey and id + */ + public static byte[] createRegionName(final byte[] tableName, + final byte[] endKey, + final long regionid, + boolean newFormat) { + return createRegionName(tableName, + null, + endKey, + Long.toString(regionid), + newFormat); + } - /** +/** * Make a region name of passed parameters. * @param tableName * @param startKey Can be null @@ -340,48 +360,95 @@ implements WritableComparable { * (such that it contains its encoded name?). * @return Region name made of passed tableName, startKey and id */ - public static byte [] createRegionName(final byte [] tableName, - final byte [] startKey, final byte [] id, boolean newFormat) { - byte [] b = new byte [tableName.length + 2 + id.length + - (startKey == null? 0: startKey.length) + - (newFormat ? (MD5_HEX_LENGTH + 2) : 0)]; - - int offset = tableName.length; - System.arraycopy(tableName, 0, b, 0, offset); - b[offset++] = DELIMITER; - if (startKey != null && startKey.length > 0) { - System.arraycopy(startKey, 0, b, offset, startKey.length); - offset += startKey.length; + public static byte [] createRegionName(final byte[] tableName, + final byte[] startKey, + final byte[] endKey, + final String id, + boolean newFormat) { + return createRegionName(tableName, + startKey, + endKey, + Bytes.toBytes(id), + newFormat); + } + /** + * Make a region name of passed parameters. + * + * @param tableName + * @param startKey Can be null + * @param endKey Can be null + * @param id Region id (Usually timestamp from when region was + * created). + * @param newFormat should we create the region name in the new format + * (such that it contains its encoded name?). + * @return Region name made of passed tableName, endKey and id + */ + + public static byte[] createRegionName(final byte[] tableName, + final byte[] startKey, + final byte[] endKey, + final byte[] id, + boolean newFormat) { + // Allocate room for the tablename along with the end of table + // marker and the delimiter. + int allocation = tableName.length + 2; + + // If the endKey is null just allocate space for the delimiter, else + // allocate enough for the key and a delimiter + allocation += endKey == null ? 1 : endKey.length + 1; + allocation += id == null ? 0 : id.length; + + ByteBuffer byteArrayDataOutput = MappedByteBuffer.allocate(allocation); + byteArrayDataOutput.put(tableName); + + if (endKey == null || endKey.length <= 0) { + byteArrayDataOutput.put((byte)END_OF_TABLE_NAME_FOR_EMPTY_ENDKEY); + byteArrayDataOutput.put((byte)DELIMITER); + } else { + byteArrayDataOutput.put((byte)END_OF_TABLE_NAME); + byteArrayDataOutput.put((byte)DELIMITER); + byteArrayDataOutput.put(endKey); + } + byteArrayDataOutput.put((byte)DELIMITER); + + if (id != null && id.length > 0) { + byteArrayDataOutput.put(id); + } + + if (newFormat) { + return addEncoding(byteArrayDataOutput.array(), startKey); + } else { + return byteArrayDataOutput.array(); + } } - b[offset++] = DELIMITER; - System.arraycopy(id, 0, b, offset, id.length); - offset += id.length; - - if (newFormat) { - // - // Encoded name should be built into the region name. - // - // Use the region name thus far (namely, ,,) - // to compute a MD5 hash to be used as the encoded name, and append - // it to the byte buffer. - // - String md5Hash = MD5Hash.getMD5AsHex(b, 0, offset); - byte [] md5HashBytes = Bytes.toBytes(md5Hash); - - if (md5HashBytes.length != MD5_HEX_LENGTH) { - LOG.error("MD5-hash length mismatch: Expected=" + MD5_HEX_LENGTH + - "; Got=" + md5HashBytes.length); - } - // now append the bytes '..' to the end - b[offset++] = ENC_SEPARATOR; - System.arraycopy(md5HashBytes, 0, b, offset, MD5_HEX_LENGTH); - offset += MD5_HEX_LENGTH; - b[offset++] = ENC_SEPARATOR; + private static byte[] addEncoding(final byte[] metaKey, + final byte[] startKey) { + + + // + // Encoded name should be built into the region name. + // + // Use the region name thus far (namely, tablename followed by ! or " + // ! means it is not the last region in the table + // and " means that it is the last region in the table. ,,) + // to compute a MD5 hash to be used as the encoded name, and append + // it to the byte buffer. + // + + final byte[] md5HashBytes = MD5Hash.getMD5AsHex(metaKey).getBytes(); + + if (md5HashBytes.length != MD5_HEX_LENGTH) { + LOG.error("MD5-hash length mismatch: Expected=" + MD5_HEX_LENGTH + + "; Got=" + md5HashBytes.length); + } + + byte[] encoding = Bytes.add(new byte[]{ENC_SEPARATOR}, + md5HashBytes, + new byte[]{ENC_SEPARATOR}); + return Bytes.add(metaKey, encoding); } - - return b; - } + /** * Gets the table name from the specified region name. @@ -392,7 +459,7 @@ implements WritableComparable { int offset = -1; for (int i = 0; i < regionName.length; i++) { if (regionName[i] == DELIMITER) { - offset = i; + offset = i - 1; break; } } @@ -401,47 +468,49 @@ implements WritableComparable { return tableName; } - /** - * Separate elements of a regionName. - * @param regionName - * @return Array of byte[] containing tableName, startKey and id - * @throws IOException - */ - public static byte [][] parseRegionName(final byte [] regionName) - throws IOException { - int offset = -1; - for (int i = 0; i < regionName.length; i++) { - if (regionName[i] == DELIMITER) { - offset = i; - break; - } + /** + * Separate elements of a regionName. + * + * @param regionName + * @return Array of byte[] containing the tablename, endKey and id + * @throws IOException + */ + public static byte[][] parseRegionName(final byte[] regionName) + throws IOException { + int offset = -1; + + for (int i = 0; i < regionName.length; i++) { + if (regionName[i] == DELIMITER) { + offset = i - 1; + break; + } + } + if (offset == -1) throw new IOException("Invalid regionName format"); + byte[] tableName = new byte[offset]; + System.arraycopy(regionName, 0, tableName, 0, offset); + offset = -1; + for (int i = regionName.length - 1; i > 0; i--) { + if (regionName[i] == DELIMITER) { + offset = i; + break; + } + } + if (offset == -1) throw new IOException("Invalid regionName format"); + byte[] endKey = HConstants.EMPTY_BYTE_ARRAY; + if (offset != tableName.length + 1) { + endKey = new byte[offset - tableName.length - 1]; + System.arraycopy(regionName, tableName.length + 1, endKey, 0, + offset - tableName.length - 1); + } + byte[] id = new byte[regionName.length - offset - 1]; + System.arraycopy(regionName, offset + 1, id, 0, + regionName.length - offset - 1); + byte[][] elements = new byte[3][]; + elements[0] = tableName; + elements[1] = endKey; + elements[2] = id; + return elements; } - if(offset == -1) throw new IOException("Invalid regionName format"); - byte [] tableName = new byte[offset]; - System.arraycopy(regionName, 0, tableName, 0, offset); - offset = -1; - for (int i = regionName.length - 1; i > 0; i--) { - if(regionName[i] == DELIMITER) { - offset = i; - break; - } - } - if(offset == -1) throw new IOException("Invalid regionName format"); - byte [] startKey = HConstants.EMPTY_BYTE_ARRAY; - if(offset != tableName.length + 1) { - startKey = new byte[offset - tableName.length - 1]; - System.arraycopy(regionName, tableName.length + 1, startKey, 0, - offset - tableName.length - 1); - } - byte [] id = new byte[regionName.length - offset - 1]; - System.arraycopy(regionName, offset + 1, id, 0, - regionName.length - offset - 1); - byte [][] elements = new byte[3][]; - elements[0] = tableName; - elements[1] = startKey; - elements[2] = id; - return elements; - } /** @return the regionId */ public long getRegionId(){ diff --git src/main/java/org/apache/hadoop/hbase/HTableDescriptor.java src/main/java/org/apache/hadoop/hbase/HTableDescriptor.java index 133759d..10eec21 100644 --- src/main/java/org/apache/hadoop/hbase/HTableDescriptor.java +++ src/main/java/org/apache/hadoop/hbase/HTableDescriptor.java @@ -258,13 +258,65 @@ public class HTableDescriptor implements WritableComparable { } } - /* - * Set meta flags on this table. - * IS_ROOT_KEY is set if its a -ROOT- table - * IS_META_KEY is set either if its a -ROOT- or a .META. table - * Called by constructors. - * @param name - */ + /** + * This gives you a stop row for scanning for a particular region in meta. + * It's important that we don't scan past the end of the regions for a + * particular table. + * + * @param tableName The tablename in meta in which we want + * to provide a stopRow for scanning for. + * @return The stopRow to prevent scanning past the last region in meta for + * a table. + */ + + public static byte[] getStopRow(final byte[] tableName) { + final int allocation = tableName.length + 3; + byte[] b = new byte[allocation]; + int offset = tableName.length; + System.arraycopy(tableName, 0, b, 0, offset); + + b[offset++] = (byte) (HRegionInfo.END_OF_TABLE_NAME_FOR_EMPTY_ENDKEY + 1); + b[offset++] = HRegionInfo.DELIMITER; + b[offset++] = HRegionInfo.DELIMITER; + return b; + } + + /** + * Get the first possible region that could match a particular + * tablename and searchrow. + * + * @param tableName The tableName in which we are searching for the matching + * region. + * @param searchRow The row in which we are searching for the matching region + * @return The first possible matching region. + */ + public static byte[] getStartRow(final byte[] tableName, + final byte[] searchRow) { + + if (searchRow == null || searchRow.length == 0) { + final int allocation = tableName.length + 3; + byte[] startRow = new byte[allocation]; + System.arraycopy(tableName, 0, startRow, 0, tableName.length); + startRow[tableName.length] = HRegionInfo.END_OF_TABLE_NAME - 1; + startRow[tableName.length + 1] = HRegionInfo.DELIMITER; + startRow[tableName.length + 2] = HRegionInfo.DELIMITER; + return startRow; + } + + return HRegionInfo.createRegionName(tableName, + null, + searchRow, + HConstants.NINES, + false); + } + + /* + * Set meta flags on this table. + * IS_ROOT_KEY is set if its a -ROOT- table + * IS_META_KEY is set either if its a -ROOT- or a .META. table + * Called by constructors. + * @param name + */ private void setMetaFlags(final byte [] name) { setRootRegion(Bytes.equals(name, HConstants.ROOT_TABLE_NAME)); setMetaRegion(isRootRegion() || diff --git src/main/java/org/apache/hadoop/hbase/KeyValue.java src/main/java/org/apache/hadoop/hbase/KeyValue.java index be7e2d8..4a40cb0 100644 --- src/main/java/org/apache/hadoop/hbase/KeyValue.java +++ src/main/java/org/apache/hadoop/hbase/KeyValue.java @@ -1896,7 +1896,7 @@ public class KeyValue implements Writable, HeapSize { // Rows look like this: .META.,ROW_FROM_META,RID // LOG.info("ROOT " + Bytes.toString(left, loffset, llength) + // "---" + Bytes.toString(right, roffset, rlength)); - final int metalength = 7; // '.META.' length + final int metalength = 8; // '.META.' length int lmetaOffsetPlusDelimiter = loffset + metalength; int leftFarDelimiter = getDelimiterInReverse(left, lmetaOffsetPlusDelimiter, diff --git src/main/java/org/apache/hadoop/hbase/catalog/MetaReader.java src/main/java/org/apache/hadoop/hbase/catalog/MetaReader.java index e5e60a8..97a33e1 100644 --- src/main/java/org/apache/hadoop/hbase/catalog/MetaReader.java +++ src/main/java/org/apache/hadoop/hbase/catalog/MetaReader.java @@ -443,7 +443,9 @@ public class MetaReader { this.results.add(this.current); } }; - fullScan(catalogTracker, visitor, getTableStartRowForMeta(tableNameBytes)); + byte[] startRow = HTableDescriptor.getStartRow(tableName.getBytes(), + HConstants.EMPTY_BYTE_ARRAY); + fullScan(catalogTracker, visitor, startRow); // If visitor has results >= 1 then table exists. return visitor.getResults().size() >= 1; } @@ -502,18 +504,7 @@ public class MetaReader { return Bytes.equals(tableName, current.getTableName()); } - /** - * @param tableName - * @return Place to start Scan in .META. when passed a - * tableName; returns <tableName&rt; <,&rt; <,&rt; - */ - static byte [] getTableStartRowForMeta(final byte [] tableName) { - byte [] startRow = new byte[tableName.length + 2]; - System.arraycopy(tableName, 0, startRow, 0, tableName.length); - startRow[startRow.length - 2] = HRegionInfo.DELIMITER; - startRow[startRow.length - 1] = HRegionInfo.DELIMITER; - return startRow; - } + /** * This method creates a Scan object that will only scan catalog rows that @@ -527,12 +518,12 @@ public class MetaReader { public static Scan getScanForTableName(byte[] tableName) { String strName = Bytes.toString(tableName); // Start key is just the table name with delimiters - byte[] startKey = Bytes.toBytes(strName + ",,"); + byte[] startKey = HTableDescriptor.getStartRow(tableName, + HConstants.EMPTY_BYTE_ARRAY); // Stop key appends the smallest possible char to the table name - byte[] stopKey = Bytes.toBytes(strName + " ,,"); + byte[] stopKey = HTableDescriptor.getStopRow(tableName); - Scan scan = new Scan(startKey); - scan.setStopRow(stopKey); + Scan scan = new Scan(startKey, stopKey); return scan; } @@ -547,7 +538,7 @@ public class MetaReader { getTableRegionsAndLocations(CatalogTracker catalogTracker, String tableName) throws IOException, InterruptedException { return getTableRegionsAndLocations(catalogTracker, Bytes.toBytes(tableName), - true); + true); } /** @@ -597,8 +588,10 @@ public class MetaReader { this.results.add(this.current); } }; - fullScan(catalogTracker, visitor, getTableStartRowForMeta(tableName), - Bytes.equals(tableName, HConstants.META_TABLE_NAME)); + byte[] startRow = HTableDescriptor.getStartRow(tableName, + HConstants.EMPTY_BYTE_ARRAY); + boolean isMeta = Bytes.equals(tableName, HConstants.META_TABLE_NAME); + fullScan(catalogTracker, visitor, startRow, isMeta); return visitor.getResults(); } diff --git src/main/java/org/apache/hadoop/hbase/client/HBaseAdmin.java src/main/java/org/apache/hadoop/hbase/client/HBaseAdmin.java index 88c381f..6ca3c34 100644 --- src/main/java/org/apache/hadoop/hbase/client/HBaseAdmin.java +++ src/main/java/org/apache/hadoop/hbase/client/HBaseAdmin.java @@ -1553,8 +1553,8 @@ public class HBaseAdmin implements Abortable, Closeable { private HRegionLocation getFirstMetaServerForTable(final byte [] tableName) throws IOException { - return connection.locateRegion(HConstants.META_TABLE_NAME, - HRegionInfo.createRegionName(tableName, null, HConstants.NINES, false)); + byte[] metaRowKey = HTableDescriptor.getStartRow(tableName, null); + return connection.locateRegion(HConstants.META_TABLE_NAME, metaRowKey); } /** diff --git src/main/java/org/apache/hadoop/hbase/client/HConnectionManager.java src/main/java/org/apache/hadoop/hbase/client/HConnectionManager.java index 99f90b2..c934aa5 100644 --- src/main/java/org/apache/hadoop/hbase/client/HConnectionManager.java +++ src/main/java/org/apache/hadoop/hbase/client/HConnectionManager.java @@ -822,8 +822,13 @@ public class HConnectionManager { return null; } } else if (Bytes.equals(tableName, HConstants.META_TABLE_NAME)) { - return locateRegionInMeta(HConstants.ROOT_TABLE_NAME, tableName, row, - useCache, metaRegionLock); + + //HARD CODED TO POINT TO THE FIRST META TABLE + return locateRegionInMeta(HConstants.ROOT_TABLE_NAME, + HConstants.META_TABLE_NAME, + HConstants.EMPTY_BYTE_ARRAY, + useCache, + metaRegionLock); } else { // Region not in the cache - have to go to the meta RS return locateRegionInMeta(HConstants.META_TABLE_NAME, tableName, row, @@ -891,9 +896,51 @@ public class HConnectionManager { } } + + private HRegionInfo resultToHRegionInfo(final Result result, + byte[] tableName, + byte[] parentTable) + throws IOException { + + if (result == null) { + throw new TableNotFoundException(Bytes.toString(tableName)); + } + + byte[] value = result.getValue(HConstants.CATALOG_FAMILY, + HConstants.REGIONINFO_QUALIFIER); + + if (value == null || value.length == 0) { + throw new IOException("HRegionInfo was null or empty in " + + Bytes.toString(parentTable) + + ", row=" + + result); + } + + HRegionInfo regionInfo = Writables.getHRegionInfo(value); + + // possible we got a region of a different table... + + if (!Bytes.equals(regionInfo.getTableName(), tableName)) { + String errorMsg = "Table '" + Bytes.toString(tableName) + "' was not found, got: "; + if (regionInfo != null) { + errorMsg += Bytes.toString(regionInfo.getTableName()) + "."; + } + throw new TableNotFoundException(errorMsg); + } + + return regionInfo; + } + private boolean finishedScanningForRegion(HRegionInfo regionInfo) { + if (regionInfo == null || regionInfo.isOffline() || regionInfo.isSplit()) { + return false; + } + return true; + } + /* * Search one of the meta tables (-ROOT- or .META.) for the HRegionLocation - * info that contains the table and row we're seeking. + * info that contains the table and row we're seeking. If the row is null or 0 length + * then return a key which scans to the first meta key for the table. */ private HRegionLocation locateRegionInMeta(final byte [] parentTable, final byte [] tableName, final byte [] row, boolean useCache, @@ -909,17 +956,13 @@ public class HConnectionManager { } } - // build the key of the meta region we should be looking for. - // the extra 9's on the end are necessary to allow "exact" matches - // without knowing the precise region names. - byte [] metaKey = HRegionInfo.createRegionName(tableName, row, - HConstants.NINES, false); + final byte [] metaKey = HTableDescriptor.getStartRow(tableName, row); for (int tries = 0; true; tries++) { if (tries >= numRetries) { throw new NoServerForRegionException("Unable to find region for " + Bytes.toStringBinary(row) + " after " + numRetries + " tries."); } - + Result regionInfoRow = null; HRegionLocation metaLocation = null; try { // locate the root or meta region @@ -929,10 +972,11 @@ public class HConnectionManager { HRegionInterface server = getHRegionConnection(metaLocation.getHostname(), metaLocation.getPort()); - Result regionInfoRow = null; // This block guards against two threads trying to load the meta // region at the same time. The first will load the meta region and // the second will use the value that the first one found. + + HRegionInfo regionInfo = null; synchronized (regionLockObject) { // If the parent table is META, we may want to pre-fetch some // region info into the global region cache for this table. @@ -954,46 +998,62 @@ public class HConnectionManager { deleteCachedLocation(tableName, row); } - // Query the root or meta region for the location of the meta region - regionInfoRow = server.getClosestRowBefore( - metaLocation.getRegionInfo().getRegionName(), metaKey, - HConstants.CATALOG_FAMILY); - } - if (regionInfoRow == null) { - throw new TableNotFoundException(Bytes.toString(tableName)); - } - byte [] value = regionInfoRow.getValue(HConstants.CATALOG_FAMILY, - HConstants.REGIONINFO_QUALIFIER); - if (value == null || value.length == 0) { - throw new IOException("HRegionInfo was null or empty in " + - Bytes.toString(parentTable) + ", row=" + regionInfoRow); - } - // convert the row result into the HRegionLocation we need! - HRegionInfo regionInfo = (HRegionInfo) Writables.getWritable( - value, new HRegionInfo()); - // possible we got a region of a different table... - if (!Bytes.equals(regionInfo.getTableName(), tableName)) { - throw new TableNotFoundException( - "Table '" + Bytes.toString(tableName) + "' was not found, got: " + - Bytes.toString(regionInfo.getTableName()) + "."); + byte[] stopRow = HTableDescriptor.getStopRow(tableName); + Scan scan = new Scan(metaKey).addFamily(HConstants.CATALOG_FAMILY); + byte[] regionName = metaLocation.getRegionInfo().getRegionName(); + long scannerId = server.openScanner(regionName, scan); + + // We always try to get two rows just in case one of them is a split. + Result[] result = server.next(scannerId, 2); + + // We haven't cleared the meta entry out of the table yet + if (result == null || result.length <= 0 ) { + throw new TableNotFoundException("Table '" + Bytes.toString(tableName) + + " we searched for the StartKey: " + Bytes.toString(metaKey) + + " startKey lastChar's int value: " + (int) metaKey[metaKey.length -3] + + " with the stopKey: " + Bytes.toString(stopRow) + + " stopRow lastChar's int value: " + (int) stopRow[stopRow.length -3] + + " with parentTable:" + Bytes.toString(parentTable)); + } else if (result.length == 2) { + regionInfoRow = result[0]; + regionInfo = resultToHRegionInfo(regionInfoRow, + tableName, + parentTable); + if (regionInfo.isOffline()) { + regionInfoRow = result[1]; + regionInfo = resultToHRegionInfo(regionInfoRow, + tableName, + parentTable); + } + } else { + regionInfoRow = result[0]; + regionInfo = resultToHRegionInfo(regionInfoRow, tableName, parentTable); + } + } + + if (regionInfo == null) { + throw new TableNotFoundException("Table '" + + Bytes.toString(tableName) + "' was not found, got: " + + Bytes.toString(regionInfo.getTableName()) + "."); } + if (regionInfo.isSplit()) { throw new RegionOfflineException("the only available region for" + - " the required row is a split parent," + - " the daughters should be online soon: " + - regionInfo.getRegionNameAsString()); + " the required row is a split parent," + + " the daughters should be online soon: " + + regionInfo.getRegionNameAsString()); } if (regionInfo.isOffline()) { throw new RegionOfflineException("the region is offline, could" + - " be caused by a disable table call: " + - regionInfo.getRegionNameAsString()); + " be caused by a disable table call: " + + regionInfo.getRegionNameAsString()); } - value = regionInfoRow.getValue(HConstants.CATALOG_FAMILY, - HConstants.SERVER_QUALIFIER); String hostAndPort = ""; - if (value != null) { - hostAndPort = Bytes.toString(value); + if (regionInfoRow.getValue(HConstants.CATALOG_FAMILY, + HConstants.SERVER_QUALIFIER) != null) { + hostAndPort = Bytes.toString(regionInfoRow.getValue(HConstants.CATALOG_FAMILY, + HConstants.SERVER_QUALIFIER)); } if (hostAndPort.equals("")) { throw new NoServerForRegionException("No server address listed " + @@ -1849,4 +1909,4 @@ public class HConnectionManager { c.setInt(HConstants.HBASE_CLIENT_RETRIES_NUMBER, retries); log.debug("Set serverside HConnection retries=" + retries); } -} \ No newline at end of file +} diff --git src/main/java/org/apache/hadoop/hbase/client/MetaScanner.java src/main/java/org/apache/hadoop/hbase/client/MetaScanner.java index f0c6828..f557168 100644 --- src/main/java/org/apache/hadoop/hbase/client/MetaScanner.java +++ src/main/java/org/apache/hadoop/hbase/client/MetaScanner.java @@ -31,8 +31,8 @@ import org.apache.commons.logging.LogFactory; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.hbase.HConstants; import org.apache.hadoop.hbase.HRegionInfo; +import org.apache.hadoop.hbase.HTableDescriptor; import org.apache.hadoop.hbase.ServerName; -import org.apache.hadoop.hbase.TableNotFoundException; import org.apache.hadoop.hbase.client.HConnectionManager.HConnectable; import org.apache.hadoop.hbase.util.Bytes; import org.apache.hadoop.hbase.util.Writables; @@ -138,39 +138,17 @@ public class MetaScanner { // if row is not null, we want to use the startKey of the row's region as // the startRow for the meta scan. - byte[] startRow; - if (row != null) { - // Scan starting at a particular row in a particular table - assert tableName != null; - byte[] searchRow = - HRegionInfo.createRegionName(tableName, row, HConstants.NINES, - false); - HTable metaTable = new HTable(configuration, HConstants.META_TABLE_NAME); - Result startRowResult = metaTable.getRowOrBefore(searchRow, - HConstants.CATALOG_FAMILY); - if (startRowResult == null) { - throw new TableNotFoundException("Cannot find row in .META. for table: " - + Bytes.toString(tableName) + ", row=" + Bytes.toStringBinary(searchRow)); - } - byte[] value = startRowResult.getValue(HConstants.CATALOG_FAMILY, - HConstants.REGIONINFO_QUALIFIER); - if (value == null || value.length == 0) { - throw new IOException("HRegionInfo was null or empty in Meta for " + - Bytes.toString(tableName) + ", row=" + Bytes.toStringBinary(searchRow)); - } - HRegionInfo regionInfo = Writables.getHRegionInfo(value); + byte[] startRow; + byte[] stopRow; - byte[] rowBefore = regionInfo.getStartKey(); - startRow = HRegionInfo.createRegionName(tableName, rowBefore, - HConstants.ZEROES, false); - } else if (tableName == null || tableName.length == 0) { + if (tableName == null || tableName.length == 0) { // Full META scan startRow = HConstants.EMPTY_START_ROW; + stopRow = null; } else { - // Scan META for an entire table - startRow = HRegionInfo.createRegionName( - tableName, HConstants.EMPTY_START_ROW, HConstants.ZEROES, false); + startRow = HTableDescriptor.getStartRow(tableName, row); + stopRow = HTableDescriptor.getStopRow(tableName); } // Scan over each meta region @@ -178,8 +156,15 @@ public class MetaScanner { int rows = Math.min(rowLimit, configuration.getInt( HConstants.HBASE_META_SCANNER_CACHING, HConstants.DEFAULT_HBASE_META_SCANNER_CACHING)); + do { - final Scan scan = new Scan(startRow).addFamily(HConstants.CATALOG_FAMILY); + Scan scan; + if (stopRow != null) { // Support full meta scans + scan = new Scan(startRow, stopRow).addFamily(HConstants.CATALOG_FAMILY); + } else { + scan = new Scan(startRow).addFamily(HConstants.CATALOG_FAMILY); + } + if (LOG.isDebugEnabled()) { LOG.debug("Scanning " + Bytes.toString(metaTableName) + " starting at row=" + Bytes.toStringBinary(startRow) + " for max=" + diff --git src/main/java/org/apache/hadoop/hbase/rest/RegionsResource.java src/main/java/org/apache/hadoop/hbase/rest/RegionsResource.java index bf85bc1..be5db4c 100644 --- src/main/java/org/apache/hadoop/hbase/rest/RegionsResource.java +++ src/main/java/org/apache/hadoop/hbase/rest/RegionsResource.java @@ -21,8 +21,8 @@ package org.apache.hadoop.hbase.rest; import java.io.IOException; -import java.net.InetSocketAddress; import java.util.Map; +import java.util.NavigableMap; import javax.ws.rs.GET; import javax.ws.rs.Produces; @@ -37,7 +37,7 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.hadoop.hbase.HRegionInfo; -import org.apache.hadoop.hbase.HServerAddress; +import org.apache.hadoop.hbase.ServerName; import org.apache.hadoop.hbase.TableNotFoundException; import org.apache.hadoop.hbase.client.HTable; import org.apache.hadoop.hbase.client.HTableInterface; @@ -67,12 +67,12 @@ public class RegionsResource extends ResourceBase { this.tableResource = tableResource; } - private Map getTableRegions() + private NavigableMap getTableRegions() throws IOException { HTablePool pool = servlet.getTablePool(); HTableInterface table = pool.getTable(tableResource.getName()); try { - return ((HTable)table).getRegionsInfo(); + return ((HTable)table).getRegionLocations(); } finally { pool.putTable(table); } @@ -88,15 +88,14 @@ public class RegionsResource extends ResourceBase { try { String tableName = tableResource.getName(); TableInfoModel model = new TableInfoModel(tableName); - Map regions = getTableRegions(); - for (Map.Entry e: regions.entrySet()) { + NavigableMap regions = getTableRegions(); + for (Map.Entry e: regions.entrySet()) { HRegionInfo hri = e.getKey(); - HServerAddress addr = e.getValue(); - InetSocketAddress sa = addr.getInetSocketAddress(); + ServerName addr = e.getValue(); model.add( new TableRegionModel(tableName, hri.getRegionId(), hri.getStartKey(), hri.getEndKey(), - sa.getHostName() + ":" + Integer.valueOf(sa.getPort()))); + addr.getHostname() + ":" + Integer.valueOf(addr.getPort()))); } ResponseBuilder response = Response.ok(model); response.cacheControl(cacheControl); diff --git src/main/java/org/apache/hadoop/hbase/rest/model/TableRegionModel.java src/main/java/org/apache/hadoop/hbase/rest/model/TableRegionModel.java index 67e7a04..17f699f 100644 --- src/main/java/org/apache/hadoop/hbase/rest/model/TableRegionModel.java +++ src/main/java/org/apache/hadoop/hbase/rest/model/TableRegionModel.java @@ -66,8 +66,7 @@ public class TableRegionModel implements Serializable { * @param startKey the start key of the region * @param endKey the end key of the region */ - public TableRegionModel(String table, long id, byte[] startKey, - byte[] endKey) { + public TableRegionModel(String table, long id, byte[] startKey, byte[] endKey) { this(table, id, startKey, endKey, null); } @@ -79,8 +78,7 @@ public class TableRegionModel implements Serializable { * @param endKey the end key of the region * @param location the name and port of the region server hosting the region */ - public TableRegionModel(String table, long id, byte[] startKey, - byte[] endKey, String location) { + public TableRegionModel(String table, long id, byte[] startKey, byte[] endKey, String location) { this.table = table; this.id = id; this.startKey = startKey; @@ -95,9 +93,11 @@ public class TableRegionModel implements Serializable { public String getName() { byte [] tableNameAsBytes = Bytes.toBytes(this.table); byte [] nameAsBytes = HRegionInfo.createRegionName(tableNameAsBytes, - this.startKey, this.id, - !HTableDescriptor.isMetaTable(tableNameAsBytes)); - return Bytes.toString(nameAsBytes); + this.startKey, + this.endKey, + Long.toString(this.id).getBytes(), + !HTableDescriptor.isMetaTable(tableNameAsBytes)); + return Bytes.toStringBinary(nameAsBytes); } /** @@ -109,6 +109,14 @@ public class TableRegionModel implements Serializable { } /** + * @return the table name + */ + @XmlAttribute + public String getTable() { + return table; + } + + /** * @return the start key */ @XmlAttribute @@ -133,15 +141,10 @@ public class TableRegionModel implements Serializable { } /** - * @param name region printable name + * @param table the table name */ - public void setName(String name) { - String split[] = name.split(","); - this.table = split[0]; - this.startKey = Bytes.toBytes(split[1]); - String tail = split[2]; - split = tail.split("\\."); - id = Long.valueOf(split[0]); + public void setTable(String table) { + this.table = table; } /** @@ -185,6 +188,8 @@ public class TableRegionModel implements Serializable { sb.append(Bytes.toString(startKey)); sb.append("'\n endKey='"); sb.append(Bytes.toString(endKey)); + sb.append("'\n table='"); + sb.append(table); if (location != null) { sb.append("'\n location='"); sb.append(location); diff --git src/test/java/org/apache/hadoop/hbase/TestKeyValue.java src/test/java/org/apache/hadoop/hbase/TestKeyValue.java index dc4ee8d..7b076d5 100644 --- src/test/java/org/apache/hadoop/hbase/TestKeyValue.java +++ src/test/java/org/apache/hadoop/hbase/TestKeyValue.java @@ -116,12 +116,14 @@ public class TestKeyValue extends TestCase { public void testMoreComparisons() throws Exception { // Root compares long now = System.currentTimeMillis(); - KeyValue a = new KeyValue(Bytes.toBytes(".META.,,99999999999999"), now); - KeyValue b = new KeyValue(Bytes.toBytes(".META.,,1"), now); + String lastMeta = ".META.\",,99999999999999"; + String firstMeta = ".META.\",,1"; + KeyValue a = new KeyValue(Bytes.toBytes(lastMeta), now); + KeyValue b = new KeyValue(Bytes.toBytes(firstMeta), now); KVComparator c = new KeyValue.RootComparator(); assertTrue(c.compare(b, a) < 0); - KeyValue aa = new KeyValue(Bytes.toBytes(".META.,,1"), now); - KeyValue bb = new KeyValue(Bytes.toBytes(".META.,,1"), + KeyValue aa = new KeyValue(Bytes.toBytes(firstMeta), now); + KeyValue bb = new KeyValue(Bytes.toBytes(firstMeta), Bytes.toBytes("info"), Bytes.toBytes("regioninfo"), 1235943454602L, (byte[])null); assertTrue(c.compare(aa, bb) < 0); diff --git src/test/java/org/apache/hadoop/hbase/regionserver/TestGetClosestAtOrBefore.java src/test/java/org/apache/hadoop/hbase/regionserver/TestGetClosestAtOrBefore.java index 5f97167..f0f88a5 100644 --- src/test/java/org/apache/hadoop/hbase/regionserver/TestGetClosestAtOrBefore.java +++ src/test/java/org/apache/hadoop/hbase/regionserver/TestGetClosestAtOrBefore.java @@ -55,88 +55,6 @@ public class TestGetClosestAtOrBefore extends HBaseTestCase { private static final byte[] T35 = Bytes.toBytes("035"); private static final byte[] T40 = Bytes.toBytes("040"); - - - public void testUsingMetaAndBinary() throws IOException { - FileSystem filesystem = FileSystem.get(conf); - Path rootdir = testDir; - // Up flush size else we bind up when we use default catalog flush of 16k. - HTableDescriptor.META_TABLEDESC.setMemStoreFlushSize(64 * 1024 * 1024); - - HRegion mr = HRegion.createHRegion(HRegionInfo.FIRST_META_REGIONINFO, - rootdir, this.conf, HTableDescriptor.META_TABLEDESC); - try { - // Write rows for three tables 'A', 'B', and 'C'. - for (char c = 'A'; c < 'D'; c++) { - HTableDescriptor htd = new HTableDescriptor("" + c); - final int last = 128; - final int interval = 2; - for (int i = 0; i <= last; i += interval) { - HRegionInfo hri = new HRegionInfo(htd.getName(), - i == 0? HConstants.EMPTY_BYTE_ARRAY: Bytes.toBytes((byte)i), - i == last? HConstants.EMPTY_BYTE_ARRAY: Bytes.toBytes((byte)i + interval)); - Put put = new Put(hri.getRegionName()); - put.setWriteToWAL(false); - put.add(HConstants.CATALOG_FAMILY, HConstants.REGIONINFO_QUALIFIER, - Writables.getBytes(hri)); - mr.put(put, false); - } - } - InternalScanner s = mr.getScanner(new Scan()); - try { - List keys = new ArrayList(); - while(s.next(keys)) { - LOG.info(keys); - keys.clear(); - } - } finally { - s.close(); - } - findRow(mr, 'C', 44, 44); - findRow(mr, 'C', 45, 44); - findRow(mr, 'C', 46, 46); - findRow(mr, 'C', 43, 42); - mr.flushcache(); - findRow(mr, 'C', 44, 44); - findRow(mr, 'C', 45, 44); - findRow(mr, 'C', 46, 46); - findRow(mr, 'C', 43, 42); - // Now delete 'C' and make sure I don't get entries from 'B'. - byte [] firstRowInC = HRegionInfo.createRegionName(Bytes.toBytes("" + 'C'), - HConstants.EMPTY_BYTE_ARRAY, HConstants.ZEROES, false); - Scan scan = new Scan(firstRowInC); - s = mr.getScanner(scan); - try { - List keys = new ArrayList(); - while (s.next(keys)) { - mr.delete(new Delete(keys.get(0).getRow()), null, false); - keys.clear(); - } - } finally { - s.close(); - } - // Assert we get null back (pass -1). - findRow(mr, 'C', 44, -1); - findRow(mr, 'C', 45, -1); - findRow(mr, 'C', 46, -1); - findRow(mr, 'C', 43, -1); - mr.flushcache(); - findRow(mr, 'C', 44, -1); - findRow(mr, 'C', 45, -1); - findRow(mr, 'C', 46, -1); - findRow(mr, 'C', 43, -1); - } finally { - if (mr != null) { - try { - mr.close(); - } catch (Exception e) { - e.printStackTrace(); - } - mr.getLog().closeAndDelete(); - } - } - } - /* * @param mr * @param table @@ -152,7 +70,7 @@ public class TestGetClosestAtOrBefore extends HBaseTestCase { // Find the row. byte [] tofindBytes = Bytes.toBytes((short)rowToFind); byte [] metaKey = HRegionInfo.createRegionName(tableb, tofindBytes, - HConstants.NINES, false); + 99999999999999l, false); LOG.info("find=" + new String(metaKey)); Result r = mr.getClosestRowBefore(metaKey); if (answer == -1) { diff --git src/test/java/org/apache/hadoop/hbase/regionserver/TestHRegionInfo.java src/test/java/org/apache/hadoop/hbase/regionserver/TestHRegionInfo.java index 6e1211b..0657ae3 100644 --- src/test/java/org/apache/hadoop/hbase/regionserver/TestHRegionInfo.java +++ src/test/java/org/apache/hadoop/hbase/regionserver/TestHRegionInfo.java @@ -43,20 +43,23 @@ public class TestHRegionInfo { final byte [] tn = Bytes.toBytes(tableName); String startKey = "startkey"; final byte [] sk = Bytes.toBytes(startKey); - String id = "id"; + String endKey = "endkey"; + final byte [] ek = Bytes.toBytes(endKey); + + String id = "id"; // old format region name - byte [] name = HRegionInfo.createRegionName(tn, sk, id, false); + byte [] name = HRegionInfo.createRegionName(tn, sk, ek, id, false); String nameStr = Bytes.toString(name); - assertEquals(tableName + "," + startKey + "," + id, nameStr); + assertEquals(tableName + "!," + endKey + "," + id, nameStr); // new format region name. String md5HashInHex = MD5Hash.getMD5AsHex(name); assertEquals(HRegionInfo.MD5_HEX_LENGTH, md5HashInHex.length()); - name = HRegionInfo.createRegionName(tn, sk, id, true); + name = HRegionInfo.createRegionName(tn, sk, ek, id, true); nameStr = Bytes.toString(name); - assertEquals(tableName + "," + startKey + "," + assertEquals(tableName + "!," + endKey + "," + id + "." + md5HashInHex + ".", nameStr); } diff --git src/test/java/org/apache/hadoop/hbase/rest/TestStatusResource.java src/test/java/org/apache/hadoop/hbase/rest/TestStatusResource.java index cffdcb6..108c9a1 100644 --- src/test/java/org/apache/hadoop/hbase/rest/TestStatusResource.java +++ src/test/java/org/apache/hadoop/hbase/rest/TestStatusResource.java @@ -27,6 +27,8 @@ import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBException; import org.apache.hadoop.hbase.HBaseTestingUtility; +import org.apache.hadoop.hbase.HConstants; +import org.apache.hadoop.hbase.HRegionInfo; import org.apache.hadoop.hbase.MediumTests; import org.apache.hadoop.hbase.rest.client.Client; import org.apache.hadoop.hbase.rest.client.Cluster; @@ -42,8 +44,19 @@ import org.junit.experimental.categories.Category; @Category(MediumTests.class) public class TestStatusResource { - private static final byte[] ROOT_REGION_NAME = Bytes.toBytes("-ROOT-,,0"); - private static final byte[] META_REGION_NAME = Bytes.toBytes(".META.,,1"); + + private static final byte[] ROOT_REGION_NAME = HRegionInfo.createRegionName(HConstants.ROOT_TABLE_NAME, + HConstants.EMPTY_BYTE_ARRAY, + HConstants.EMPTY_BYTE_ARRAY, + "0".getBytes(), + false); + + private static final byte[] META_REGION_NAME = HRegionInfo.createRegionName(HConstants.META_TABLE_NAME, + HConstants.EMPTY_BYTE_ARRAY, + HConstants.EMPTY_BYTE_ARRAY, + "1".getBytes(), + false); + private static final HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility(); private static final HBaseRESTTestingUtility REST_TEST_UTIL = diff --git src/test/java/org/apache/hadoop/hbase/rest/model/TestTableRegionModel.java src/test/java/org/apache/hadoop/hbase/rest/model/TestTableRegionModel.java index b6f0ab5..754c04b 100644 --- src/test/java/org/apache/hadoop/hbase/rest/model/TestTableRegionModel.java +++ src/test/java/org/apache/hadoop/hbase/rest/model/TestTableRegionModel.java @@ -45,7 +45,8 @@ public class TestTableRegionModel extends TestCase { " endKey=\"enp5eng=\"" + " startKey=\"YWJyYWNhZGJyYQ==\"" + " id=\"8731042424\"" + - " name=\"testtable,abracadbra,8731042424\"/>"; + " table=\"testtable\"" + + " name=\"testtable,zzyzx,8731042424\"/>"; private JAXBContext context; @@ -55,9 +56,7 @@ public class TestTableRegionModel extends TestCase { } private TableRegionModel buildTestModel() { - TableRegionModel model = - new TableRegionModel(TABLE, ID, START_KEY, END_KEY, LOCATION); - return model; + return new TableRegionModel(TABLE, ID, START_KEY, END_KEY, LOCATION); } @SuppressWarnings("unused") @@ -77,9 +76,12 @@ public class TestTableRegionModel extends TestCase { assertTrue(Bytes.equals(model.getEndKey(), END_KEY)); assertEquals(model.getId(), ID); assertEquals(model.getLocation(), LOCATION); - assertEquals(model.getName(), - TABLE + "," + Bytes.toString(START_KEY) + "," + Long.toString(ID) + - ".ad9860f031282c46ed431d7af8f94aca."); + byte[] regionInfo = HRegionInfo.createRegionName(TABLE.getBytes(), + START_KEY, + END_KEY, + Long.toString(ID).getBytes(), + true); + assertEquals(model.getName(), Bytes.toStringBinary(regionInfo)); } public void testBuildModel() throws Exception { @@ -90,17 +92,13 @@ public class TestTableRegionModel extends TestCase { TableRegionModel model = buildTestModel(); String modelName = model.getName(); HRegionInfo hri = new HRegionInfo(Bytes.toBytes(TABLE), - START_KEY, END_KEY, false, ID); + START_KEY, + END_KEY, + false, + ID); assertEquals(modelName, hri.getRegionNameAsString()); } - public void testSetName() { - TableRegionModel model = buildTestModel(); - String name = model.getName(); - model.setName(name); - assertEquals(name, model.getName()); - } - public void testFromXML() throws Exception { checkModel(fromXML(AS_XML)); } -- 1.7.4.4