diff --git security/src/main/java/org/apache/hadoop/hbase/security/access/AccessController.java security/src/main/java/org/apache/hadoop/hbase/security/access/AccessController.java index c1f20de..b636e3e 100644 --- security/src/main/java/org/apache/hadoop/hbase/security/access/AccessController.java +++ security/src/main/java/org/apache/hadoop/hbase/security/access/AccessController.java @@ -673,14 +673,6 @@ public class AccessController extends BaseRegionObserver } @Override - public void preGetClosestRowBefore(final ObserverContext c, - final byte [] row, final byte [] family, final Result result) - throws IOException { - requirePermission(TablePermission.Action.READ, c.getEnvironment(), - (family != null ? Lists.newArrayList(family) : null)); - } - - @Override public void preGet(final ObserverContext c, final Get get, final List result) throws IOException { /* diff --git src/main/java/org/apache/hadoop/hbase/HConstants.java src/main/java/org/apache/hadoop/hbase/HConstants.java index 07041b5..5de107a 100644 --- src/main/java/org/apache/hadoop/hbase/HConstants.java +++ src/main/java/org/apache/hadoop/hbase/HConstants.java @@ -48,7 +48,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 @@ -62,9 +65,11 @@ public final class HConstants { * Version 5 changes versions in catalog table regions. * Version 6 enables blockcaching on catalog tables. * Version 7 introduces hfile -- hbase 0.19 to 0.20.. + * version 8 changed the metaFormat */ // public static final String FILE_SYSTEM_VERSION = "6"; - public static final String FILE_SYSTEM_VERSION = "7"; + public static final String FILE_SYSTEM_VERSION = "8"; + public static final int FILE_SYSTEM_VERSION_INT = Integer.parseInt(FILE_SYSTEM_VERSION); // Configuration parameters @@ -82,9 +87,6 @@ public final class HConstants { /** Cluster is fully-distributed */ public static final String CLUSTER_IS_DISTRIBUTED = "true"; - /** Default value for cluster distributed mode */ - public static final String DEFAULT_CLUSTER_DISTRIBUTED = CLUSTER_IS_LOCAL; - /** default host address */ public static final String DEFAULT_HOST = "0.0.0.0"; @@ -270,7 +272,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? @@ -293,9 +295,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"; @@ -336,6 +335,8 @@ public final class HConstants { * meta is up-to-date. */ public static final short META_VERSION = 0; + public static final short META_VERSION2 = 1; + // Other constants diff --git src/main/java/org/apache/hadoop/hbase/HRegionInfo.java src/main/java/org/apache/hadoop/hbase/HRegionInfo.java index 8d83ff3..561460c 100644 --- src/main/java/org/apache/hadoop/hbase/HRegionInfo.java +++ src/main/java/org/apache/hadoop/hbase/HRegionInfo.java @@ -23,6 +23,7 @@ import java.io.DataInput; import java.io.DataOutput; import java.io.EOFException; import java.io.IOException; +import java.nio.ByteBuffer; import java.util.Arrays; import org.apache.commons.logging.Log; @@ -33,7 +34,10 @@ 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.migration.HRegionInfo090x2; import org.apache.hadoop.hbase.util.Bytes; import org.apache.hadoop.hbase.util.FSTableDescriptors; import org.apache.hadoop.hbase.util.JenkinsHash; @@ -52,7 +56,8 @@ public class HRegionInfo extends VersionedWritable implements WritableComparable { // VERSION == 0 when HRegionInfo had an HTableDescriptor inside it. public static final byte VERSION_PRE_092 = 0; - public static final byte VERSION = 1; + public static final byte VERSION = 2; + private static final Log LOG = LogFactory.getLog(HRegionInfo.class); /** @@ -61,13 +66,15 @@ implements WritableComparable { * in the filesystem. * * New region name format: - * <tablename>,,<startkey>,<regionIdTimestamp>.<encodedName>. + * <tablename><is_end_of_table_marker>,,<endkey>,<regionIdTimestamp>.<encodedName>. * where, + * <end_of_table_marker> HRegionInfo.NOT_END_OF_TABLE + * || HRegionInfo.END_OF_TABLE * <encodedName> is a hex version of the MD5 hash of - * <tablename>,<startkey>,<regionIdTimestamp> + * <tablename>,&<startkey>,<regionIdTimestamp> * * The old region name format: - * <tablename>,<startkey>,<regionIdTimestamp> + * <tablename>,<is_end_of_table_marker><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). *

@@ -83,6 +90,14 @@ implements WritableComparable { */ private static final int ENC_SEPARATOR = '.'; public static final int MD5_HEX_LENGTH = 32; + // It should say, the tablename encoded in the region ends with !, + // but the last region's tablename ends with " + public static final int NOT_END_OF_TABLE = 33; // The ascii for ! + + // This must come after NOT_END_OF_TABLE to work + public static final int END_OF_TABLE = NOT_END_OF_TABLE + 1; + public static final String ROOT_REGION_ENCODING = "1756551925"; + public static final String META_REGION_ENCODING = "845716343"; /** * Does region name contain its encoded name? @@ -108,7 +123,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); @@ -125,15 +140,19 @@ implements WritableComparable { /** * Use logging. * @param encodedRegionName The encoded regionname. - * @return -ROOT- if passed 70236052 or - * .META. if passed 1028785192 else returns + * @return -ROOT- if passed + * HRegionInfo.ROOT_REGION_ENCODING or + * .META. if passed + * HRegionInfo.META_REGION_ENCODING else returns * encodedRegionName */ public static String prettyPrint(final String encodedRegionName) { - if (encodedRegionName.equals("70236052")) { + if (encodedRegionName.equals(ROOT_REGION_ENCODING)) { return encodedRegionName + "/-ROOT-"; - } else if (encodedRegionName.equals("1028785192")) { - return encodedRegionName + "/.META."; + } else { + if (encodedRegionName.equals(META_REGION_ENCODING)) { + return encodedRegionName + "/.META."; + } } return encodedRegionName; } @@ -143,11 +162,12 @@ implements WritableComparable { /** 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.")); + public static final HRegionInfo + FIRST_META_REGIONINFO = + 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 @@ -217,6 +237,32 @@ implements WritableComparable { this.tableName = other.getTableDesc().getName(); } + + /** + * Used only for migration + * @param other HRegionInfoForMigration + */ + public HRegionInfo(HRegionInfo090x2 other) { + super(); + this.endKey = other.getEndKey(); + this.offLine = other.isOffline(); + this.regionId = other.getRegionId(); + this.split = other.isSplit(); + this.startKey = other.getStartKey(); + this.hashCode = other.hashCode(); + this.encodedName = other.getEncodedName(); + this.tableName = other.getTableName(); + if (Arrays.equals(this.tableName, HConstants.META_TABLE_NAME) || + Arrays.equals(this.tableName, HConstants.ROOT_TABLE_NAME)) { + this.regionName = createRegionName(tableName, startKey, endKey, regionId, false); + } else { + this.regionName = createRegionName(tableName, startKey, endKey, regionId, true); + } + this.regionNameStr = Bytes.toStringBinary(this.regionName); + + } + + public HRegionInfo(final byte[] tableName) { this(tableName, null, null); } @@ -276,7 +322,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; @@ -287,7 +337,19 @@ implements WritableComparable { setHashCode(); } - /** + private byte[] createRegionName(byte[] tableName, + byte[] startKey, + byte[] endKey, + long regionId, + boolean newFormat) { + return createRegionName(tableName, + startKey, + endKey, + Long.toString(regionId), + newFormat); + } + + /** * Costruct a copy of another HRegionInfo * * @param other @@ -307,33 +369,28 @@ 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 endKey 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, 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. @@ -344,48 +401,114 @@ 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 = ByteBuffer.allocate(allocation); + byteArrayDataOutput.put(tableName); + + if (endKey == null || endKey.length <= 0) { + byteArrayDataOutput.put((byte) END_OF_TABLE); + byteArrayDataOutput.put((byte)DELIMITER); + } else { + byteArrayDataOutput.put((byte) NOT_END_OF_TABLE); + byteArrayDataOutput.put((byte)DELIMITER); + byteArrayDataOutput.put(endKey); + } + byteArrayDataOutput.put((byte)DELIMITER); + + if (id != null && id.length > 0) { + byteArrayDataOutput.put(id); + } + + // Add the encoding bit to the regionname if it is a new style region. + if (newFormat) { + return addEncoding(byteArrayDataOutput.array(), + tableName, + startKey, + id); + } else { + // Old style regions have no encoding so just return. + 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; + /** + * Encoded name should be built into the region name. + * As not to change encodings between the pre-HBASE-2600 + * versions and the post versions + * We want to use the startkey as opposed to the endkey + * here so as not to change encodings. + * @param regionName The regionName without an encoding + * @param tableName The table name. + * @param startKey The startKey. + * @param id The region id + * @return The region with the encoding glued on. + */ + private static byte[] addEncoding(final byte[] regionName, + final byte[] tableName, + final byte[] startKey, + final byte[] id) { + + + byte [] oldRegionKey = Bytes.add(tableName, new byte[] {DELIMITER}); + if (startKey != null) { + oldRegionKey = Bytes.add(oldRegionKey, startKey, new byte[] {DELIMITER}); + } else { + oldRegionKey = Bytes.add(oldRegionKey, + HConstants.EMPTY_BYTE_ARRAY, + new byte[] {DELIMITER}); + } + oldRegionKey = Bytes.add(oldRegionKey, id); + + final byte[] md5HashBytes = MD5Hash.getMD5AsHex(oldRegionKey).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(regionName, encoding); } - - return b; - } + /** * Gets the table name from the specified region name. @@ -396,7 +519,8 @@ implements WritableComparable { int offset = -1; for (int i = 0; i < regionName.length; i++) { if (regionName[i] == DELIMITER) { - offset = i; + // We are off by one because we need to remove the end of region marker + offset = i - 1; break; } } @@ -405,47 +529,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; - } - } - 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); + /** + * 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; } - 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(){ @@ -723,36 +849,58 @@ implements WritableComparable { // because freaks out if its not the current classes' version. This method // can deserialize version 0 and version 1 of HRI. byte version = in.readByte(); - if (version == 0) { - // This is the old HRI that carried an HTD. Migrate it. The below - // was copied from the old 0.90 HRI readFields. - this.endKey = Bytes.readByteArray(in); - this.offLine = in.readBoolean(); - this.regionId = in.readLong(); - this.regionName = Bytes.readByteArray(in); - this.regionNameStr = Bytes.toStringBinary(this.regionName); - this.split = in.readBoolean(); - this.startKey = Bytes.readByteArray(in); - try { - HTableDescriptor htd = new HTableDescriptor(); - htd.readFields(in); - this.tableName = htd.getName(); - } catch(EOFException eofe) { - throw new IOException("HTD not found in input buffer", eofe); - } - this.hashCode = in.readInt(); - } else if (getVersion() == version) { - this.endKey = Bytes.readByteArray(in); - this.offLine = in.readBoolean(); - this.regionId = in.readLong(); - this.regionName = Bytes.readByteArray(in); - this.regionNameStr = Bytes.toStringBinary(this.regionName); - this.split = in.readBoolean(); - this.startKey = Bytes.readByteArray(in); - this.tableName = Bytes.readByteArray(in); - this.hashCode = in.readInt(); - } else { - throw new IOException("Non-migratable/unknown version=" + getVersion()); + switch (version) { + case HRegionInfo.VERSION: + this.endKey = Bytes.readByteArray(in); + this.offLine = in.readBoolean(); + this.regionId = in.readLong(); + this.regionName = Bytes.readByteArray(in); + this.split = in.readBoolean(); + this.startKey = Bytes.readByteArray(in); + this.tableName = Bytes.readByteArray(in); + this.hashCode = in.readInt(); + this.regionNameStr = Bytes.toStringBinary(this.regionName); + break; + case HRegionInfo090x2.VERSION: + this.endKey = Bytes.readByteArray(in); + this.offLine = in.readBoolean(); + this.regionId = in.readLong(); + this.regionName = Bytes.readByteArray(in); + this.split = in.readBoolean(); + this.startKey = Bytes.readByteArray(in); + this.tableName = Bytes.readByteArray(in); + this.hashCode = in.readInt(); + if (Arrays.equals(this.tableName, HConstants.META_TABLE_NAME) || + Arrays.equals(this.tableName, HConstants.ROOT_TABLE_NAME)) { + this.regionName = createRegionName(tableName, startKey, endKey, regionId, false); + } else { + this.regionName = createRegionName(tableName, startKey, endKey, regionId, true); + } + this.regionNameStr = Bytes.toStringBinary(this.regionName); + break; + case VERSION_PRE_092: + // This is the old HRI that carried an HTD. Migrate it. The below + // was copied from the old 0.90 HRI readFields. + this.endKey = Bytes.readByteArray(in); + this.offLine = in.readBoolean(); + this.regionId = in.readLong(); + this.regionName = Bytes.readByteArray(in); + this.split = in.readBoolean(); + this.startKey = Bytes.readByteArray(in); + try { + HTableDescriptor htd = new HTableDescriptor(); + htd.readFields(in); + this.tableName = htd.getName(); + } catch (EOFException eofe) { + throw new IOException("HTD not found in input buffer", eofe); + } + this.hashCode = in.readInt(); + this.regionNameStr = Bytes.toStringBinary(this.regionName); + break; + default: + String errMsg = "Non-migratable/unknown version=" + version; + errMsg += " .It should be= " + getVersion(); + throw new IOException(errMsg); } } diff --git src/main/java/org/apache/hadoop/hbase/HServerLoad.java src/main/java/org/apache/hadoop/hbase/HServerLoad.java index fcf529f..5d703b9 100644 --- src/main/java/org/apache/hadoop/hbase/HServerLoad.java +++ src/main/java/org/apache/hadoop/hbase/HServerLoad.java @@ -274,30 +274,8 @@ implements WritableComparable { public long getWriteRequestsCount() { return writeRequestsCount; } - - /** - * @return The current total size of root-level indexes for the region, in KB. - */ - public int getRootIndexSizeKB() { - return rootIndexSizeKB; - } - - /** - * @return The total size of all index blocks, not just the root level, in KB. - */ - public int getTotalStaticIndexSizeKB() { - return totalStaticIndexSizeKB; - } /** - * @return The total size of all Bloom filter blocks, not just loaded into the - * block cache, in KB. - */ - public int getTotalStaticBloomSizeKB() { - return totalStaticBloomSizeKB; - } - - /** * @return the total number of kvs in current compaction */ public long getTotalCompactingKVs() { diff --git src/main/java/org/apache/hadoop/hbase/HTableDescriptor.java src/main/java/org/apache/hadoop/hbase/HTableDescriptor.java index fc5e53e..e544b5b 100644 --- src/main/java/org/apache/hadoop/hbase/HTableDescriptor.java +++ src/main/java/org/apache/hadoop/hbase/HTableDescriptor.java @@ -35,8 +35,6 @@ import org.apache.hadoop.classification.InterfaceAudience; import org.apache.hadoop.classification.InterfaceStability; import org.apache.hadoop.fs.Path; import org.apache.hadoop.hbase.io.ImmutableBytesWritable; -import org.apache.hadoop.hbase.io.hfile.Compression; -import org.apache.hadoop.hbase.regionserver.StoreFile; import org.apache.hadoop.hbase.security.User; import org.apache.hadoop.hbase.util.Bytes; import org.apache.hadoop.io.WritableComparable; @@ -262,13 +260,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 + 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.NOT_END_OF_TABLE - 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 243d76f..1535de5 100644 --- src/main/java/org/apache/hadoop/hbase/KeyValue.java +++ src/main/java/org/apache/hadoop/hbase/KeyValue.java @@ -1916,10 +1916,10 @@ public class KeyValue implements Writable, HeapSize { public static class RootKeyComparator extends MetaKeyComparator { public int compareRows(byte [] left, int loffset, int llength, byte [] right, int roffset, int rlength) { - // Rows look like this: .META.,ROW_FROM_META,RID - // LOG.info("ROOT " + Bytes.toString(left, loffset, llength) + + // 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/MetaMigratev2.java src/main/java/org/apache/hadoop/hbase/catalog/MetaMigratev2.java new file mode 100644 index 0000000..409671c --- /dev/null +++ src/main/java/org/apache/hadoop/hbase/catalog/MetaMigratev2.java @@ -0,0 +1,324 @@ +/** + * 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.catalog; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.hadoop.conf.Configuration; +import org.apache.hadoop.fs.FileSystem; +import org.apache.hadoop.fs.Path; +import org.apache.hadoop.hbase.HConstants; +import org.apache.hadoop.hbase.HRegionInfo; +import org.apache.hadoop.hbase.catalog.MetaReader.Visitor; +import org.apache.hadoop.hbase.client.*; +import org.apache.hadoop.hbase.master.AssignmentManager; +import org.apache.hadoop.hbase.master.MasterFileSystem; +import org.apache.hadoop.hbase.master.MasterServices; +import org.apache.hadoop.hbase.migration.HRegionInfo090x2; +import org.apache.hadoop.hbase.util.Bytes; +import org.apache.hadoop.hbase.util.FSUtils; +import org.apache.hadoop.hbase.util.Writables; +import org.apache.zookeeper.KeeperException; + +import java.io.IOException; +import java.util.*; + +public class MetaMigratev2 { + + private static final Log LOG = LogFactory.getLog(MetaMigratev2.class); + private MasterFileSystem masterFileSystem; + private FileSystem fs; + private MasterServices masterServices; + + /** + * A class to check and update the version of Root and Meta + * + * @param hMaster The HMaster's master service + */ + public MetaMigratev2(MasterServices hMaster) { + masterServices = hMaster; + masterFileSystem = masterServices.getMasterFileSystem(); + fs = masterFileSystem.getFileSystem(); + } + + /** + * Meta visitor that migrates the info:regioninfo as it visits. + */ + class MigratingMetaVisitor implements Visitor { + private final MasterServices services; + final List htds = new ArrayList(); + + MigratingMetaVisitor(final MasterServices services) { + this.services = services; + } + + @Override + public boolean visit(Result r) throws IOException { + if (r == null || r.isEmpty()) return true; + // Check info:regioninfo, info:splitA, and info:splitB. Make sure all + // have migrated HRegionInfos... that there are no leftover 090 version + // HRegionInfos. + byte[] hriBytes = getBytes(r, HConstants.REGIONINFO_QUALIFIER); + // Presumes that an edit updating all three cells either succeeds or + // doesn't -- that we don't have case of info:regioninfo migrated but not + // info:splitA. + if (isMigrated(hriBytes)) return true; + // OK. Need to migrate this row in meta. + HRegionInfo090x2 hri090 = getHRegionInfo090x2(hriBytes); + Delete d = new Delete(hri090.getRegionName()); + + // This will 'migrate' the hregioninfo from 090 version to 092. + HRegionInfo hri = new HRegionInfo(hri090); + LOG.error("Migrating from hri090:" + hri090 + "=> to hri:" + hri); + + // Now make a put to write back to meta. + Put p = new Put(hri.getRegionName()); + p.add(HConstants.CATALOG_FAMILY, HConstants.REGIONINFO_QUALIFIER, + Writables.getBytes(hri)); + + // Now check info:splitA and info:splitB if present. Migrate these too. + checkSplit(r, p, HConstants.SPLITA_QUALIFIER); + checkSplit(r, p, HConstants.SPLITB_QUALIFIER); + + MetaEditor.putToMetaTable(this.services.getCatalogTracker(), p); + MetaEditor.deleteMetaTable(this.services.getCatalogTracker(), d); + + htds.add(hri); + return true; + } + } + + void checkSplit(final Result r, final Put p, final byte[] which) + throws IOException { + //XXX do I need to remove splits, we need a test for this + byte[] hriSplitBytes = getBytes(r, which); + if (!isMigrated(hriSplitBytes)) { + // This will convert the HRI from 092v1 to 092v2 HRI. + // If we can't migrate the children throw an IOException. + HRegionInfo090x2 hri902 = Writables.getHRegionInfo90x2(hriSplitBytes); + // This will 'migrate' the hregioninfo from 090x2 version to 092. + HRegionInfo hri = new HRegionInfo(hri902); + + p.add(HConstants.CATALOG_FAMILY, which, Writables.getBytes(hri)); + } + } + + /** + * Get the version of roottable + * + * @return the version of the root table + * @throws IOException if we can't recover the hbase version. + */ + public int getVersion() throws IOException { + Path rootDir = masterFileSystem.getRootDir(); + return Integer.parseInt(FSUtils.getVersion(fs, rootDir)); + } + + /** + * Update legacy META rows + * + * @return List of table descriptors. + * @throws IOException In case we can't metaScan + */ + List updateMeta() throws IOException { + MigratingMetaVisitor v = new MigratingMetaVisitor(masterServices); + MetaReader.fullScan(masterServices.getCatalogTracker(), v); + + AssignmentManager assignmentManager = masterServices.getAssignmentManager(); + assignmentManager.setRegionsToReopen(v.htds); + return v.htds; + } + + boolean isRootOnline() throws IOException, InterruptedException { + Configuration configuration = masterServices.getConfiguration(); + int defaultTimeout = 1000; + long timeout = configuration.getLong("hbase.catalog.verification.timeout", + defaultTimeout); + CatalogTracker catalogTracker = masterServices.getCatalogTracker(); + return catalogTracker.verifyRootRegionLocation(timeout); + } + + boolean isMetaOnline() throws IOException, InterruptedException { + Configuration configuration = masterServices.getConfiguration(); + int defaultTimeout = 1000; + long timeout = configuration.getLong("hbase.catalog.verification.timeout", + defaultTimeout); + CatalogTracker catalogTracker = masterServices.getCatalogTracker(); + return catalogTracker.verifyMetaRegionLocation(timeout); + } + + void onlineRoot() throws KeeperException, InterruptedException, IOException { + if (isRootOnline()) { + LOG.error("Root is already online"); + return; + } + AssignmentManager assignmentManager = masterServices.getAssignmentManager(); + + Path metaName = new Path(masterFileSystem.getRootDir(), + new Path(Bytes.toString(HConstants.ROOT_TABLE_NAME))); + + Path oldRootRegion = new Path(metaName, "70236052"); + Path newRootRegion = new Path(metaName, HRegionInfo.ROOT_REGION_ENCODING); + + // We are recreating the new region + if (fs.exists(newRootRegion)) { + fs.delete(newRootRegion, true); + } + + //We can't support split meta regions + if (fs.exists(oldRootRegion)) { + fs.delete(oldRootRegion , true); + } + + assignmentManager.assignRoot(); + + //This guarantees that the transition has completed + assignmentManager.waitForAssignment(HRegionInfo.ROOT_REGIONINFO); + } + + + /** + * Update the ROOT with new HRI. (HRI with no HTD) + * + * @return List of table descriptors + * @throws IOException In case we can't metaScan + */ + List updateRoot() throws IOException { + HRegionInfo hri = HRegionInfo.FIRST_META_REGIONINFO; + HTable rootTable = new HTable(masterServices.getConfiguration(), + HConstants.ROOT_TABLE_NAME); + Result result = rootTable.get(new Get(hri.getRegionName())); + ArrayList retVal = new ArrayList(); + + // Make sure the preexisting root doesn't exist and we aren't overriding. + if (result.isEmpty()) { + // Now make a put to write back to meta. + Put p = new Put(hri.getRegionName()); + p.add(HConstants.CATALOG_FAMILY, + HConstants.REGIONINFO_QUALIFIER, + Writables.getBytes(hri)); + MetaEditor.putToRootTable(masterServices.getCatalogTracker(), p); + retVal.add(hri); + } + return retVal; + } + + + /** + * @param r Result to dig in. + * @param qualifier Qualifier to look at in the passed r. + * @return Bytes for an HRegionInfo or null if no bytes or empty bytes found. + */ + byte[] getBytes(final Result r, final byte[] qualifier) { + byte[] hriBytes = r.getValue(HConstants.CATALOG_FAMILY, qualifier); + if (hriBytes == null || hriBytes.length <= 0) return null; + return hriBytes; + } + + boolean isMigrated(final byte[] hriBytes) { + if (hriBytes == null || hriBytes.length <= 0) return true; + // Else, what version this HRegionInfo instance is at. The first byte + // is the version byte in a serialized HRegionInfo. If its same as our + // current HRI, then nothing to do. + + byte version = hriBytes[0]; + if (version == HRegionInfo.VERSION) { + return true; + } else if (version == HRegionInfo090x2.VERSION || version == 0 ) { + return false; + } + // Unknown version. Return true that its 'migrated' but log warning. + // Should 'never' happen. + assert false : "Unexpected version; bytes=" + Bytes.toStringBinary(hriBytes); + return true; + } + + /** + * Update and Online the new root region with information from the old one. + * + * @return Migrated htds + * @throws IOException Changes to the filesystem can trigger. + * @throws InterruptedException Changes to the zookeeper can trigger. + * @throws KeeperException Changes to the zookeeper can trigger. + */ + public List updateAndOnlineRoot() + throws IOException, InterruptedException, KeeperException { + + onlineRoot(); + return updateRoot(); + } + + /** + * Update and Online the new meta region with information from the old one. + * Also if we complete here we can set the hbase file system version. + * + * @return Migrated htds + * @throws IOException Changes to the filesystem can trigger. + * @throws InterruptedException Changes to the zookeeper can trigger. + * @throws KeeperException Changes to the zookeeper can trigger. + */ + public List updateAndOnlineMeta() + throws KeeperException, IOException, InterruptedException { + onlineMeta(); + List htds = updateMeta(); + FSUtils.setVersion(fs, + masterFileSystem.getRootDir(), + HConstants.FILE_SYSTEM_VERSION_INT, + 10); + + return htds; + } + + private void onlineMeta() throws KeeperException, IOException, InterruptedException { + + if (isMetaOnline()) { + LOG.error("Meta is already online"); + return; + } + + Path metaName = new Path(masterFileSystem.getRootDir(), + new Path(Bytes.toString(HConstants.META_TABLE_NAME))); + Path oldMetaRegion = new Path(metaName, "1028785192"); + Path newMetaRegion = new Path(metaName, HRegionInfo.META_REGION_ENCODING); + + if (fs.exists(newMetaRegion)) { + fs.delete(newMetaRegion, true); + } + + fs.rename(oldMetaRegion, newMetaRegion); + this.masterServices.getAssignmentManager().assignMeta(); + } + + /** + * Get HRegionInfoForMigration serialized from bytes. + * + * @param bytes serialized bytes + * @return An instance of a 090 HRI or null if we failed deserialize + */ + HRegionInfo090x2 getHRegionInfo090x2(final byte[] bytes) { + if (bytes == null || bytes.length == 0) return null; + HRegionInfo090x2 hri = null; + try { + hri = (HRegionInfo090x2) Writables.getWritable(bytes, new HRegionInfo090x2()); + } catch (IOException ioe) { + LOG.warn("Failed deserialize as a 090 HRegionInfo); bytes=" + + Bytes.toStringBinary(bytes), ioe); + } + return hri; + } +} diff --git src/main/java/org/apache/hadoop/hbase/catalog/MetaReader.java src/main/java/org/apache/hadoop/hbase/catalog/MetaReader.java index 0129ee9..fff74dd 100644 --- src/main/java/org/apache/hadoop/hbase/catalog/MetaReader.java +++ src/main/java/org/apache/hadoop/hbase/catalog/MetaReader.java @@ -447,7 +447,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; } @@ -506,18 +508,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 @@ -531,12 +522,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; } @@ -601,8 +592,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 16e4017..995e261 100644 --- src/main/java/org/apache/hadoop/hbase/client/HBaseAdmin.java +++ src/main/java/org/apache/hadoop/hbase/client/HBaseAdmin.java @@ -1588,8 +1588,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 b2a5463..d1df47a 100644 --- src/main/java/org/apache/hadoop/hbase/client/HConnectionManager.java +++ src/main/java/org/apache/hadoop/hbase/client/HConnectionManager.java @@ -937,8 +937,12 @@ public class HConnectionManager { zkw.close(); } } 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, @@ -1006,9 +1010,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, @@ -1024,17 +1070,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 @@ -1044,10 +1086,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. @@ -1069,29 +1112,42 @@ 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); + + Result result; + do { + result = server.next(scannerId); + if (result != null ){ + regionInfoRow = result; + regionInfo = resultToHRegionInfo(regionInfoRow, + tableName, + parentTable); + if (! regionInfo.isOffline()) { + break; + } + } + } while (result != null); + + // We haven't cleared the meta entry out of the table yet + if (result == null) { + 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)); + } + } + 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," + @@ -1104,11 +1160,11 @@ public class HConnectionManager { 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 " + diff --git src/main/java/org/apache/hadoop/hbase/client/HTable.java src/main/java/org/apache/hadoop/hbase/client/HTable.java index 8e7d7f7..e27b7e8 100644 --- src/main/java/org/apache/hadoop/hbase/client/HTable.java +++ src/main/java/org/apache/hadoop/hbase/client/HTable.java @@ -615,20 +615,6 @@ public class HTable implements HTableInterface { return allRegions; } - /** - * {@inheritDoc} - */ - @Override - public Result getRowOrBefore(final byte[] row, final byte[] family) - throws IOException { - return new ServerCallable(connection, tableName, row, operationTimeout) { - public Result call() throws IOException { - return server.getClosestRowBefore(location.getRegionInfo().getRegionName(), - row, family); - } - }.withRetries(); - } - /** * {@inheritDoc} */ diff --git src/main/java/org/apache/hadoop/hbase/client/HTableInterface.java src/main/java/org/apache/hadoop/hbase/client/HTableInterface.java index 04150ad..348380a 100644 --- src/main/java/org/apache/hadoop/hbase/client/HTableInterface.java +++ src/main/java/org/apache/hadoop/hbase/client/HTableInterface.java @@ -134,23 +134,6 @@ public interface HTableInterface extends Closeable { Result[] get(List gets) throws IOException; /** - * Return the row that matches row exactly, - * or the one that immediately precedes it. - * - * @param row A row key. - * @param family Column family to include in the {@link Result}. - * @throws IOException if a remote or network exception occurs. - * @since 0.20.0 - * - * @deprecated As of version 0.92 this method is deprecated without - * replacement. - * getRowOrBefore is used internally to find entries in .META. and makes - * various assumptions about the table (which are true for .META. but not - * in general) to be efficient. - */ - Result getRowOrBefore(byte[] row, byte[] family) throws IOException; - - /** * Returns a scanner on the current table as specified by the {@link Scan} * object. * Note that the passed {@link Scan}'s start row and caching properties diff --git src/main/java/org/apache/hadoop/hbase/client/HTablePool.java src/main/java/org/apache/hadoop/hbase/client/HTablePool.java index 47381f4..9ac6735 100755 --- src/main/java/org/apache/hadoop/hbase/client/HTablePool.java +++ src/main/java/org/apache/hadoop/hbase/client/HTablePool.java @@ -376,11 +376,6 @@ public class HTablePool implements Closeable { } @Override - public Result getRowOrBefore(byte[] row, byte[] family) throws IOException { - return table.getRowOrBefore(row, family); - } - - @Override public ResultScanner getScanner(Scan scan) throws IOException { return table.getScanner(scan); } diff --git src/main/java/org/apache/hadoop/hbase/client/MetaScanner.java src/main/java/org/apache/hadoop/hbase/client/MetaScanner.java index f404999..032f90c 100644 --- src/main/java/org/apache/hadoop/hbase/client/MetaScanner.java +++ src/main/java/org/apache/hadoop/hbase/client/MetaScanner.java @@ -33,8 +33,8 @@ import org.apache.hadoop.classification.InterfaceStability; 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; @@ -143,44 +143,15 @@ 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 = null; - try { - 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[] rowBefore = regionInfo.getStartKey(); - startRow = HRegionInfo.createRegionName(tableName, rowBefore, - HConstants.ZEROES, false); - } finally { - if (metaTable != null) { - metaTable.close(); - } - } - } else if (tableName == null || tableName.length == 0) { + byte[] stopRow; + + 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 @@ -188,8 +159,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/coprocessor/BaseRegionObserver.java src/main/java/org/apache/hadoop/hbase/coprocessor/BaseRegionObserver.java index 197eb71..dc141a7 100644 --- src/main/java/org/apache/hadoop/hbase/coprocessor/BaseRegionObserver.java +++ src/main/java/org/apache/hadoop/hbase/coprocessor/BaseRegionObserver.java @@ -105,18 +105,6 @@ public abstract class BaseRegionObserver implements RegionObserver { final Store store, final StoreFile resultFile) { } @Override - public void preGetClosestRowBefore(final ObserverContext e, - final byte [] row, final byte [] family, final Result result) - throws IOException { - } - - @Override - public void postGetClosestRowBefore(final ObserverContext e, - final byte [] row, final byte [] family, final Result result) - throws IOException { - } - - @Override public void preGet(final ObserverContext e, final Get get, final List results) throws IOException { } diff --git src/main/java/org/apache/hadoop/hbase/coprocessor/CoprocessorHost.java src/main/java/org/apache/hadoop/hbase/coprocessor/CoprocessorHost.java index 18c13c4..35dfc70 100644 --- src/main/java/org/apache/hadoop/hbase/coprocessor/CoprocessorHost.java +++ src/main/java/org/apache/hadoop/hbase/coprocessor/CoprocessorHost.java @@ -369,11 +369,6 @@ public abstract class CoprocessorHost { } } - public Result getRowOrBefore(byte[] row, byte[] family) - throws IOException { - return table.getRowOrBefore(row, family); - } - public Result get(Get get) throws IOException { return table.get(get); } diff --git src/main/java/org/apache/hadoop/hbase/coprocessor/RegionObserver.java src/main/java/org/apache/hadoop/hbase/coprocessor/RegionObserver.java index 30c61ca..5b4f42d 100644 --- src/main/java/org/apache/hadoop/hbase/coprocessor/RegionObserver.java +++ src/main/java/org/apache/hadoop/hbase/coprocessor/RegionObserver.java @@ -166,40 +166,6 @@ public interface RegionObserver extends Coprocessor { boolean abortRequested); /** - * Called before a client makes a GetClosestRowBefore request. - *

- * Call CoprocessorEnvironment#bypass to skip default actions - *

- * Call CoprocessorEnvironment#complete to skip any subsequent chained - * coprocessors - * @param c the environment provided by the region server - * @param row the row - * @param family the family - * @param result The result to return to the client if default processing - * is bypassed. Can be modified. Will not be used if default processing - * is not bypassed. - * @throws IOException if an error occurred on the coprocessor - */ - void preGetClosestRowBefore(final ObserverContext c, - final byte [] row, final byte [] family, final Result result) - throws IOException; - - /** - * Called after a client makes a GetClosestRowBefore request. - *

- * Call CoprocessorEnvironment#complete to skip any subsequent chained - * coprocessors - * @param c the environment provided by the region server - * @param row the row - * @param family the desired family - * @param result the result to return to the client, modify as necessary - * @throws IOException if an error occurred on the coprocessor - */ - void postGetClosestRowBefore(final ObserverContext c, - final byte [] row, final byte [] family, final Result result) - throws IOException; - - /** * Called before the client performs a Get *

* Call CoprocessorEnvironment#bypass to skip default actions diff --git src/main/java/org/apache/hadoop/hbase/ipc/HRegionInterface.java src/main/java/org/apache/hadoop/hbase/ipc/HRegionInterface.java index 757f98e..d501c1a 100644 --- src/main/java/org/apache/hadoop/hbase/ipc/HRegionInterface.java +++ src/main/java/org/apache/hadoop/hbase/ipc/HRegionInterface.java @@ -135,20 +135,6 @@ public interface HRegionInterface extends VersionedProtocol, Stoppable, Abortabl throws IllegalArgumentException; /** - * Return all the data for the row that matches row exactly, - * or the one that immediately preceeds it. - * - * @param regionName region name - * @param row row key - * @param family Column family to look for row in. - * @return map of values - * @throws IOException e - */ - public Result getClosestRowBefore(final byte [] regionName, - final byte [] row, final byte [] family) - throws IOException; - - /** * Perform Get operation. * @param regionName name of region to get from * @param get Get operation diff --git src/main/java/org/apache/hadoop/hbase/master/HMaster.java src/main/java/org/apache/hadoop/hbase/master/HMaster.java index dbc9251..4562256 100644 --- src/main/java/org/apache/hadoop/hbase/master/HMaster.java +++ src/main/java/org/apache/hadoop/hbase/master/HMaster.java @@ -63,6 +63,7 @@ import org.apache.hadoop.hbase.TableNotFoundException; import org.apache.hadoop.hbase.UnknownRegionException; import org.apache.hadoop.hbase.ZooKeeperConnectionException; import org.apache.hadoop.hbase.catalog.CatalogTracker; +import org.apache.hadoop.hbase.catalog.MetaMigratev2; import org.apache.hadoop.hbase.catalog.MetaReader; import org.apache.hadoop.hbase.client.HConnectionManager; import org.apache.hadoop.hbase.client.MetaScanner; @@ -563,17 +564,32 @@ Server { status.setStatus("Splitting logs after master startup"); splitLogAfterStartup(this.fileSystemManager, onlineServers); - // Make sure root and meta assigned before proceeding. - if (!assignRootAndMeta(status)) return; serverShutdownHandlerEnabled = true; this.serverManager.expireDeadNotExpiredServers(); - // Update meta with new HRI if required. i.e migrate all HRI with HTD to - // HRI with out HTD in meta and update the status in ROOT. This must happen - // before we assign all user regions or else the assignment will fail. - // TODO: Remove this when we do 0.94. - org.apache.hadoop.hbase.catalog.MetaMigrationRemovingHTD. - updateMetaWithNewHRI(this); + MetaMigratev2 metaMigratev2 = new MetaMigratev2(this); + int version = metaMigratev2.getVersion(); + // TODO: Remove this when we do 1.0 + if (version < HConstants.FILE_SYSTEM_VERSION_INT ){ + boolean rit = this.assignmentManager. + processRegionInTransitionAndBlockUntilAssigned( + HRegionInfo.ROOT_REGIONINFO); + + // Make sure root and meta assigned before proceeding. + metaMigratev2.updateAndOnlineRoot(); + + rit = this.assignmentManager. + processRegionInTransitionAndBlockUntilAssigned( + HRegionInfo.FIRST_META_REGIONINFO); + + metaMigratev2.updateAndOnlineMeta(); + + // Update meta with new HRI if required. i.e migrate all HRI with HTD to + // HRI with out HTD in meta and update the status in ROOT. This must happen + // before we assign all user regions or else the assignment will fail. + + } + assignRootAndMeta(status); // Fixup assignment manager status status.setStatus("Starting assignment manager"); diff --git src/main/java/org/apache/hadoop/hbase/master/handler/ServerShutdownHandler.java src/main/java/org/apache/hadoop/hbase/master/handler/ServerShutdownHandler.java index 2ec6677..040ab38 100644 --- src/main/java/org/apache/hadoop/hbase/master/handler/ServerShutdownHandler.java +++ src/main/java/org/apache/hadoop/hbase/master/handler/ServerShutdownHandler.java @@ -463,7 +463,7 @@ public class ServerShutdownHandler extends EventHandler { return false; } // If our start rows do not compare, move on. - if (!Bytes.equals(daughter.getStartKey(), hri.getStartKey())) { + if (!Bytes.equals(daughter.getEndKey(), hri.getEndKey())) { return false; } // Else, table name and start rows compare. It means that the daughter diff --git src/main/java/org/apache/hadoop/hbase/migration/HRegionInfo090x2.java src/main/java/org/apache/hadoop/hbase/migration/HRegionInfo090x2.java new file mode 100644 index 0000000..7e70acb --- /dev/null +++ src/main/java/org/apache/hadoop/hbase/migration/HRegionInfo090x2.java @@ -0,0 +1,763 @@ +/** + * Copyright 2007 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.migration; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.hadoop.conf.Configuration; +import org.apache.hadoop.fs.FileSystem; +import org.apache.hadoop.fs.Path; +import org.apache.hadoop.hbase.*; +import org.apache.hadoop.hbase.KeyValue.KVComparator; +import org.apache.hadoop.hbase.util.Bytes; +import org.apache.hadoop.hbase.util.FSTableDescriptors; +import org.apache.hadoop.hbase.util.JenkinsHash; +import org.apache.hadoop.hbase.util.MD5Hash; +import org.apache.hadoop.io.VersionedWritable; +import org.apache.hadoop.io.WritableComparable; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.EOFException; +import java.io.IOException; +import java.util.Arrays; + +/** + * This contains the newest old HRegionInfo class. It's used for migration. + * Migration happens via the writables interface. + */ +public class HRegionInfo090x2 extends VersionedWritable + implements WritableComparable { + // VERSION == 0 when HRegionInfo had an HTableDescriptor inside it. + public static final byte VERSION_PRE_092 = 0; + public static final byte VERSION = 1; + private static final Log LOG = LogFactory.getLog(HRegionInfo090x2.class); + + /** + * The new format for a region name contains its encodedName at the end. + * The encoded name also serves as the directory name for the region + * in the filesystem. + * + * New region name format: + * <tablename>,,<startkey>,<regionIdTimestamp>.<encodedName>. + * where, + * <encodedName> is a hex version of the MD5 hash of + * <tablename>,<startkey>,<regionIdTimestamp> + * + * The old region name format: + * <tablename>,<startkey>,<regionIdTimestamp> + * For region names in the old format, the encoded name is a 32-bit + * JenkinsHash integer value (in its decimal notation, string form). + *

+ * **NOTE** + * + * ROOT, the first META region, and regions created by an older + * version of HBase (0.20 or prior) will continue to use the + * old region name format. + */ + + /** 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; + + /** + * Does region name contain its encoded name? + * @param regionName region name + * @return boolean indicating if this a new format region + * name which contains its encoded name. + */ + private static boolean hasEncodedName(final byte[] regionName) { + // check if region name ends in ENC_SEPARATOR + if ((regionName.length >= 1) + && (regionName[regionName.length - 1] == ENC_SEPARATOR)) { + // region name is new format. it contains the encoded name. + return true; + } + return false; + } + + /** + * @param regionName + * @return the encodedName + */ + public static String encodeRegionName(final byte [] regionName) { + String encodedName; + if (hasEncodedName(regionName)) { + // region is in new format: + // ,,/encodedName/ + encodedName = Bytes.toString(regionName, + regionName.length - MD5_HEX_LENGTH - 1, + MD5_HEX_LENGTH); + } else { + // old format region name. ROOT and first META region also + // use this format.EncodedName is the JenkinsHash value. + int hashVal = Math.abs(JenkinsHash.getInstance().hash(regionName, + regionName.length, 0)); + encodedName = String.valueOf(hashVal); + } + return encodedName; + } + + /** + * Use logging. + * @param encodedRegionName The encoded regionname. + * @return -ROOT- if passed 70236052 or + * .META. if passed 1028785192 else returns + * encodedRegionName + */ + public static String prettyPrint(final String encodedRegionName) { + if (encodedRegionName.equals("70236052")) { + return encodedRegionName + "/-ROOT-"; + } else if (encodedRegionName.equals("1028785192")) { + return encodedRegionName + "/.META."; + } + return encodedRegionName; + } + + /** delimiter used between portions of a region name */ + public static final int DELIMITER = ','; + + /** HRegionInfo for root region */ + public static final HRegionInfo090x2 ROOT_REGIONINFO = + new HRegionInfo090x2(0L, Bytes.toBytes("-ROOT-")); + + /** HRegionInfo for first meta region */ + public static final HRegionInfo090x2 FIRST_META_REGIONINFO = + new HRegionInfo090x2(1L, Bytes.toBytes(".META.")); + + private byte [] endKey = HConstants.EMPTY_BYTE_ARRAY; + // This flag is in the parent of a split while the parent is still referenced + // by daughter regions. We USED to set this flag when we disabled a table + // but now table state is kept up in zookeeper as of 0.90.0 HBase. + private boolean offLine = false; + private long regionId = -1; + private transient byte [] regionName = HConstants.EMPTY_BYTE_ARRAY; + private String regionNameStr = ""; + private boolean split = false; + private byte [] startKey = HConstants.EMPTY_BYTE_ARRAY; + private int hashCode = -1; + //TODO: Move NO_HASH to HStoreFile which is really the only place it is used. + public static final String NO_HASH = null; + private volatile String encodedName = NO_HASH; + private byte [] encodedNameAsBytes = null; + + // Current TableName + private byte[] tableName = null; + + private void setHashCode() { + int result = Arrays.hashCode(this.regionName); + result ^= this.regionId; + result ^= Arrays.hashCode(this.startKey); + result ^= Arrays.hashCode(this.endKey); + result ^= Boolean.valueOf(this.offLine).hashCode(); + result ^= Arrays.hashCode(this.tableName); + this.hashCode = result; + } + + + /** + * Private constructor used constructing HRegionInfo for the catalog root and + * first meta regions + */ + private HRegionInfo090x2(long regionId, byte[] tableName) { + super(); + this.regionId = regionId; + this.tableName = tableName.clone(); + // Note: Root & First Meta regions names are still in old format + this.regionName = createRegionName(tableName, null, + regionId, false); + this.regionNameStr = Bytes.toStringBinary(this.regionName); + setHashCode(); + } + + /** Default constructor - creates empty object */ + public HRegionInfo090x2() { + super(); + } + + public HRegionInfo090x2(final byte[] tableName) { + this(tableName, null, null); + } + + /** + * Construct HRegionInfo with explicit parameters + * + * @param tableName the table name + * @param startKey first key in region + * @param endKey end of key range + * @throws IllegalArgumentException + */ + public HRegionInfo090x2(final byte[] tableName, final byte[] startKey, + final byte[] endKey) + throws IllegalArgumentException { + this(tableName, startKey, endKey, false); + } + + + /** + * Construct HRegionInfo with explicit parameters + * + * @param tableName the table descriptor + * @param startKey first key in region + * @param endKey end of key range + * @param split true if this region has split and we have daughter regions + * regions that may or may not hold references to this region. + * @throws IllegalArgumentException + */ + public HRegionInfo090x2(final byte[] tableName, final byte[] startKey, + final byte[] endKey, final boolean split) + throws IllegalArgumentException { + this(tableName, startKey, endKey, split, System.currentTimeMillis()); + } + + + /** + * Construct HRegionInfo with explicit parameters + * + * @param tableName the table descriptor + * @param startKey first key in region + * @param endKey end of key range + * @param split true if this region has split and we have daughter regions + * regions that may or may not hold references to this region. + * @param regionid Region id to use. + * @throws IllegalArgumentException + */ + public HRegionInfo090x2(final byte[] tableName, final byte[] startKey, + final byte[] endKey, final boolean split, final long regionid) + throws IllegalArgumentException { + + super(); + if (tableName == null) { + throw new IllegalArgumentException("tableName cannot be null"); + } + this.tableName = tableName.clone(); + this.offLine = false; + this.regionId = regionid; + + this.regionName = createRegionName(this.tableName, startKey, regionId, true); + + this.regionNameStr = Bytes.toStringBinary(this.regionName); + this.split = split; + this.endKey = endKey == null? HConstants.EMPTY_END_ROW: endKey.clone(); + this.startKey = startKey == null? + HConstants.EMPTY_START_ROW: startKey.clone(); + this.tableName = tableName.clone(); + setHashCode(); + } + + /** + * Costruct a copy of another HRegionInfo + * + * @param other + */ + public HRegionInfo090x2(HRegionInfo090x2 other) { + super(); + this.endKey = other.getEndKey(); + this.offLine = other.isOffline(); + this.regionId = other.getRegionId(); + this.regionName = other.getRegionName(); + this.regionNameStr = Bytes.toStringBinary(this.regionName); + this.split = other.isSplit(); + this.startKey = other.getStartKey(); + this.hashCode = other.hashCode(); + this.encodedName = other.getEncodedName(); + this.tableName = other.tableName; + } + + + /** + * 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 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 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; + } + 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; + } + + return b; + } + + /** + * Gets the table name from the specified region name. + * @param regionName + * @return Table name. + */ + public static byte [] getTableName(byte [] regionName) { + int offset = -1; + for (int i = 0; i < regionName.length; i++) { + if (regionName[i] == DELIMITER) { + offset = i; + break; + } + } + byte [] tableName = new byte[offset]; + System.arraycopy(regionName, 0, tableName, 0, offset); + 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; + } + } + 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(){ + return regionId; + } + + /** + * @return the regionName as an array of bytes. + * @see #getRegionNameAsString() + */ + public byte [] getRegionName(){ + return regionName; + } + + /** + * @return Region name as a String for use in logging, etc. + */ + public String getRegionNameAsString() { + if (hasEncodedName(this.regionName)) { + // new format region names already have their encoded name. + return this.regionNameStr; + } + + // old format. regionNameStr doesn't have the region name. + // + // + return this.regionNameStr + "." + this.getEncodedName(); + } + + /** @return the encoded region name */ + public synchronized String getEncodedName() { + if (this.encodedName == NO_HASH) { + this.encodedName = encodeRegionName(this.regionName); + } + return this.encodedName; + } + + public synchronized byte [] getEncodedNameAsBytes() { + if (this.encodedNameAsBytes == null) { + this.encodedNameAsBytes = Bytes.toBytes(getEncodedName()); + } + return this.encodedNameAsBytes; + } + + /** @return the startKey */ + public byte [] getStartKey(){ + return startKey; + } + + /** @return the endKey */ + public byte [] getEndKey(){ + return endKey; + } + + /** + * Get current table name of the region + * @return byte array of table name + */ + public byte[] getTableName() { + if (tableName == null || tableName.length == 0) { + tableName = getTableName(getRegionName()); + } + return tableName; + } + + /** + * Get current table name as string + * @return string representation of current table + */ + public String getTableNameAsString() { + return Bytes.toString(tableName); + } + + /** + * Returns true if the given inclusive range of rows is fully contained + * by this region. For example, if the region is foo,a,g and this is + * passed ["b","c"] or ["a","c"] it will return true, but if this is passed + * ["b","z"] it will return false. + * @throws IllegalArgumentException if the range passed is invalid (ie end < start) + */ + public boolean containsRange(byte[] rangeStartKey, byte[] rangeEndKey) { + if (Bytes.compareTo(rangeStartKey, rangeEndKey) > 0) { + throw new IllegalArgumentException( + "Invalid range: " + Bytes.toStringBinary(rangeStartKey) + + " > " + Bytes.toStringBinary(rangeEndKey)); + } + + boolean firstKeyInRange = Bytes.compareTo(rangeStartKey, startKey) >= 0; + boolean lastKeyInRange = + Bytes.compareTo(rangeEndKey, endKey) < 0 || + Bytes.equals(endKey, HConstants.EMPTY_BYTE_ARRAY); + return firstKeyInRange && lastKeyInRange; + } + + /** + * Return true if the given row falls in this region. + */ + public boolean containsRow(byte[] row) { + return Bytes.compareTo(row, startKey) >= 0 && + (Bytes.compareTo(row, endKey) < 0 || + Bytes.equals(endKey, HConstants.EMPTY_BYTE_ARRAY)); + } + + /** + * @return the tableDesc + * @deprecated Do not use; expensive call + * use HRegionInfo.getTableNameAsString() in place of + * HRegionInfo.getTableDesc().getNameAsString() + */ + @Deprecated + public HTableDescriptor getTableDesc() { + Configuration c = HBaseConfiguration.create(); + FileSystem fs; + try { + fs = FileSystem.get(c); + } catch (IOException e) { + throw new RuntimeException(e); + } + FSTableDescriptors fstd = + new FSTableDescriptors(fs, new Path(c.get(HConstants.HBASE_DIR))); + try { + return fstd.get(this.tableName); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + /** + * @param newDesc new table descriptor to use + * @deprecated Do not use; expensive call + */ + @Deprecated + public void setTableDesc(HTableDescriptor newDesc) { + Configuration c = HBaseConfiguration.create(); + FileSystem fs; + try { + fs = FileSystem.get(c); + } catch (IOException e) { + throw new RuntimeException(e); + } + FSTableDescriptors fstd = + new FSTableDescriptors(fs, new Path(c.get(HConstants.HBASE_DIR))); + try { + fstd.add(newDesc); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + /** @return true if this is the root region */ + public boolean isRootRegion() { + return Bytes.equals(tableName, HRegionInfo090x2.ROOT_REGIONINFO.getTableName()); + } + + /** @return true if this region is from a table that is a meta table, + * either .META. or -ROOT- + */ + public boolean isMetaTable() { + return isRootRegion() || isMetaRegion(); + } + + /** @return true if this region is a meta region */ + public boolean isMetaRegion() { + return Bytes.equals(tableName, HRegionInfo090x2.FIRST_META_REGIONINFO.getTableName()); + } + + /** + * @return True if has been split and has daughters. + */ + public boolean isSplit() { + return this.split; + } + + /** + * @param split set split status + */ + public void setSplit(boolean split) { + this.split = split; + } + + /** + * @return True if this region is offline. + */ + public boolean isOffline() { + return this.offLine; + } + + /** + * The parent of a region split is offline while split daughters hold + * references to the parent. Offlined regions are closed. + * @param offLine Set online/offline status. + */ + public void setOffline(boolean offLine) { + this.offLine = offLine; + } + + + /** + * @return True if this is a split parent region. + */ + public boolean isSplitParent() { + if (!isSplit()) return false; + if (!isOffline()) { + LOG.warn("Region is split but NOT offline: " + getRegionNameAsString()); + } + return true; + } + + /** + * @see java.lang.Object#toString() + */ + @Override + public String toString() { + return "{" + HConstants.NAME + " => '" + + this.regionNameStr + + "', STARTKEY => '" + + Bytes.toStringBinary(this.startKey) + "', ENDKEY => '" + + Bytes.toStringBinary(this.endKey) + + "', ENCODED => " + getEncodedName() + "," + + (isOffline()? " OFFLINE => true,": "") + + (isSplit()? " SPLIT => true,": "") + "}"; + } + + /** + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null) { + return false; + } + if (!(o instanceof HRegionInfo090x2)) { + return false; + } + return this.compareTo((HRegionInfo090x2)o) == 0; + } + + /** + * @see java.lang.Object#hashCode() + */ + @Override + public int hashCode() { + return this.hashCode; + } + + /** @return the object version number */ + @Override + public byte getVersion() { + return VERSION; + } + + // + // Writable + // + + @Override + public void write(DataOutput out) throws IOException { + super.write(out); + Bytes.writeByteArray(out, endKey); + out.writeBoolean(offLine); + out.writeLong(regionId); + Bytes.writeByteArray(out, regionName); + out.writeBoolean(split); + Bytes.writeByteArray(out, startKey); + Bytes.writeByteArray(out, tableName); + out.writeInt(hashCode); + } + + @Override + public void readFields(DataInput in) throws IOException { + // Read the single version byte. We don't ask the super class do it + // because freaks out if its not the current classes' version. This method + // can deserialize version 0 and version 1 of HRI. + byte version = in.readByte(); + this.endKey = Bytes.readByteArray(in); + this.offLine = in.readBoolean(); + this.regionId = in.readLong(); + this.regionName = Bytes.readByteArray(in); + this.regionNameStr = Bytes.toStringBinary(this.regionName); + this.split = in.readBoolean(); + this.startKey = Bytes.readByteArray(in); + this.tableName = Bytes.readByteArray(in); + this.hashCode = in.readInt(); + } + + // + // Comparable + // + + public int compareTo(HRegionInfo090x2 o) { + if (o == null) { + return 1; + } + + // Are regions of same table? + int result = Bytes.compareTo(this.tableName, o.tableName); + if (result != 0) { + return result; + } + + // Compare start keys. + result = Bytes.compareTo(this.startKey, o.startKey); + if (result != 0) { + return result; + } + + // Compare end keys. + result = Bytes.compareTo(this.endKey, o.endKey); + + if (result != 0) { + if (this.getStartKey().length != 0 + && this.getEndKey().length == 0) { + return 1; // this is last region + } + if (o.getStartKey().length != 0 + && o.getEndKey().length == 0) { + return -1; // o is the last region + } + return result; + } + if (this.offLine == o.offLine) + return 0; + if (this.offLine == true) return -1; + + return 1; + } + + /** + * @return Comparator to use comparing {@link KeyValue}s. + */ + public KVComparator getComparator() { + return isRootRegion()? KeyValue.ROOT_COMPARATOR: isMetaRegion()? + KeyValue.META_COMPARATOR: KeyValue.COMPARATOR; + } +} diff --git src/main/java/org/apache/hadoop/hbase/regionserver/GetClosestRowBeforeTracker.java src/main/java/org/apache/hadoop/hbase/regionserver/GetClosestRowBeforeTracker.java deleted file mode 100644 index 8174cf5..0000000 --- src/main/java/org/apache/hadoop/hbase/regionserver/GetClosestRowBeforeTracker.java +++ /dev/null @@ -1,242 +0,0 @@ -/* - * Copyright 2009 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 java.util.NavigableMap; -import java.util.NavigableSet; -import java.util.TreeMap; -import java.util.TreeSet; - -import org.apache.hadoop.classification.InterfaceAudience; -import org.apache.hadoop.hbase.HRegionInfo; -import org.apache.hadoop.hbase.KeyValue; -import org.apache.hadoop.hbase.KeyValue.KVComparator; -import org.apache.hadoop.hbase.util.Bytes; - -/** - * State and utility processing {@link HRegion#getClosestRowBefore(byte[], byte[])}. - * Like {@link ScanDeleteTracker} and {@link ScanDeleteTracker} but does not - * implement the {@link DeleteTracker} interface since state spans rows (There - * is no update nor reset method). - */ -@InterfaceAudience.Private -class GetClosestRowBeforeTracker { - private final KeyValue targetkey; - // Any cell w/ a ts older than this is expired. - private final long oldestts; - private KeyValue candidate = null; - private final KVComparator kvcomparator; - // Flag for whether we're doing getclosest on a metaregion. - private final boolean metaregion; - // Offset and length into targetkey demarking table name (if in a metaregion). - private final int rowoffset; - private final int tablenamePlusDelimiterLength; - - // Deletes keyed by row. Comparator compares on row portion of KeyValue only. - private final NavigableMap> deletes; - - /** - * @param c - * @param kv Presume first on row: i.e. empty column, maximum timestamp and - * a type of Type.Maximum - * @param ttl Time to live in ms for this Store - * @param metaregion True if this is .META. or -ROOT- region. - */ - GetClosestRowBeforeTracker(final KVComparator c, final KeyValue kv, - final long ttl, final boolean metaregion) { - super(); - this.metaregion = metaregion; - this.targetkey = kv; - // If we are in a metaregion, then our table name is the prefix on the - // targetkey. - this.rowoffset = kv.getRowOffset(); - int l = -1; - if (metaregion) { - l = KeyValue.getDelimiter(kv.getBuffer(), rowoffset, kv.getRowLength(), - HRegionInfo.DELIMITER) - this.rowoffset; - } - this.tablenamePlusDelimiterLength = metaregion? l + 1: -1; - this.oldestts = System.currentTimeMillis() - ttl; - this.kvcomparator = c; - KeyValue.RowComparator rc = new KeyValue.RowComparator(this.kvcomparator); - this.deletes = new TreeMap>(rc); - } - - /** - * @param kv - * @return True if this kv is expired. - */ - boolean isExpired(final KeyValue kv) { - return Store.isExpired(kv, this.oldestts); - } - - /* - * Add the specified KeyValue to the list of deletes. - * @param kv - */ - private void addDelete(final KeyValue kv) { - NavigableSet rowdeletes = this.deletes.get(kv); - if (rowdeletes == null) { - rowdeletes = new TreeSet(this.kvcomparator); - this.deletes.put(kv, rowdeletes); - } - rowdeletes.add(kv); - } - - /* - * @param kv Adds candidate if nearer the target than previous candidate. - * @return True if updated candidate. - */ - private boolean addCandidate(final KeyValue kv) { - if (!isDeleted(kv) && isBetterCandidate(kv)) { - this.candidate = kv; - return true; - } - return false; - } - - boolean isBetterCandidate(final KeyValue contender) { - return this.candidate == null || - (this.kvcomparator.compareRows(this.candidate, contender) < 0 && - this.kvcomparator.compareRows(contender, this.targetkey) <= 0); - } - - /* - * Check if specified KeyValue buffer has been deleted by a previously - * seen delete. - * @param kv - * @return true is the specified KeyValue is deleted, false if not - */ - private boolean isDeleted(final KeyValue kv) { - if (this.deletes.isEmpty()) return false; - NavigableSet rowdeletes = this.deletes.get(kv); - if (rowdeletes == null || rowdeletes.isEmpty()) return false; - return isDeleted(kv, rowdeletes); - } - - /** - * Check if the specified KeyValue buffer has been deleted by a previously - * seen delete. - * @param kv - * @param ds - * @return True is the specified KeyValue is deleted, false if not - */ - public boolean isDeleted(final KeyValue kv, final NavigableSet ds) { - if (deletes == null || deletes.isEmpty()) return false; - for (KeyValue d: ds) { - long kvts = kv.getTimestamp(); - long dts = d.getTimestamp(); - if (d.isDeleteFamily()) { - if (kvts <= dts) return true; - continue; - } - // Check column - int ret = Bytes.compareTo(kv.getBuffer(), kv.getQualifierOffset(), - kv.getQualifierLength(), - d.getBuffer(), d.getQualifierOffset(), d.getQualifierLength()); - if (ret <= -1) { - // This delete is for an earlier column. - continue; - } else if (ret >= 1) { - // Beyond this kv. - break; - } - // Check Timestamp - if (kvts > dts) return false; - - // Check Type - switch (KeyValue.Type.codeToType(d.getType())) { - case Delete: return kvts == dts; - case DeleteColumn: return true; - default: continue; - } - } - return false; - } - - /* - * Handle keys whose values hold deletes. - * Add to the set of deletes and then if the candidate keys contain any that - * might match, then check for a match and remove it. Implies candidates - * is made with a Comparator that ignores key type. - * @param kv - * @return True if we removed k from candidates. - */ - boolean handleDeletes(final KeyValue kv) { - addDelete(kv); - boolean deleted = false; - if (!hasCandidate()) return deleted; - if (isDeleted(this.candidate)) { - this.candidate = null; - deleted = true; - } - return deleted; - } - - /** - * Do right thing with passed key, add to deletes or add to candidates. - * @param kv - * @return True if we added a candidate - */ - boolean handle(final KeyValue kv) { - if (kv.isDelete()) { - handleDeletes(kv); - return false; - } - return addCandidate(kv); - } - - /** - * @return True if has candidate - */ - public boolean hasCandidate() { - return this.candidate != null; - } - - /** - * @return Best candidate or null. - */ - public KeyValue getCandidate() { - return this.candidate; - } - - public KeyValue getTargetKey() { - return this.targetkey; - } - - /** - * @param kv Current kv - * @param First on row kv. - * @param state - * @return True if we went too far, past the target key. - */ - boolean isTooFar(final KeyValue kv, final KeyValue firstOnRow) { - return this.kvcomparator.compareRows(kv, firstOnRow) > 0; - } - - boolean isTargetTable(final KeyValue kv) { - if (!metaregion) return true; - // Compare start of keys row. Compare including delimiter. Saves having - // to calculate where tablename ends in the candidate kv. - return Bytes.compareTo(this.targetkey.getBuffer(), this.rowoffset, - this.tablenamePlusDelimiterLength, - kv.getBuffer(), kv.getRowOffset(), this.tablenamePlusDelimiterLength) == 0; - } -} \ No newline at end of file diff --git src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java index 02d55d4..fd72640 100644 --- src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java +++ src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java @@ -1578,62 +1578,6 @@ public class HRegion implements HeapSize { // , Writable{ // get() methods for client use. ////////////////////////////////////////////////////////////////////////////// /** - * Return all the data for the row that matches row exactly, - * or the one that immediately preceeds it, at or immediately before - * ts. - * - * @param row row key - * @return map of values - * @throws IOException - */ - Result getClosestRowBefore(final byte [] row) - throws IOException{ - return getClosestRowBefore(row, HConstants.CATALOG_FAMILY); - } - - /** - * Return all the data for the row that matches row exactly, - * or the one that immediately preceeds it, at or immediately before - * ts. - * - * @param row row key - * @param family column family to find on - * @return map of values - * @throws IOException read exceptions - */ - public Result getClosestRowBefore(final byte [] row, final byte [] family) - throws IOException { - if (coprocessorHost != null) { - Result result = new Result(); - if (coprocessorHost.preGetClosestRowBefore(row, family, result)) { - return result; - } - } - // look across all the HStores for this region and determine what the - // closest key is across all column families, since the data may be sparse - checkRow(row, "getClosestRowBefore"); - startRegionOperation(); - this.readRequestsCount.increment(); - try { - Store store = getStore(family); - // get the closest key. (HStore.getRowKeyAtOrBefore can return null) - KeyValue key = store.getRowKeyAtOrBefore(row); - Result result = null; - if (key != null) { - Get get = new Get(key.getRow()); - get.addFamily(family); - result = get(get, null); - } - if (coprocessorHost != null) { - coprocessorHost.postGetClosestRowBefore(row, family, result); - } - return result; - } finally { - closeRegionOperation(); - } - } - - /** * Return an iterator that scans over the HRegion, returning the indicated * columns and rows specified by the {@link Scan}. *

@@ -3196,6 +3140,7 @@ public class HRegion implements HeapSize { // , Writable{ byte[] familyName = p.getFirst(); String path = p.getSecond(); + Store store = getStore(familyName); if (store == null) { IOException ioe = new DoNotRetryIOException( diff --git src/main/java/org/apache/hadoop/hbase/regionserver/HRegionServer.java src/main/java/org/apache/hadoop/hbase/regionserver/HRegionServer.java index e0af8fb..c1365a2 100644 --- src/main/java/org/apache/hadoop/hbase/regionserver/HRegionServer.java +++ src/main/java/org/apache/hadoop/hbase/regionserver/HRegionServer.java @@ -1934,22 +1934,6 @@ public class HRegionServer implements HRegionInterface, HBaseRPCErrorHandler, return getRegion(regionName).getRegionInfo(); } - public Result getClosestRowBefore(final byte[] regionName, final byte[] row, - final byte[] family) throws IOException { - checkOpen(); - requestCount.incrementAndGet(); - try { - // locate the region we're operating on - HRegion region = getRegion(regionName); - // ask the region for all the data - - Result r = region.getClosestRowBefore(row, family); - return r; - } catch (Throwable t) { - throw convertThrowableToIOE(cleanup(t)); - } - } - /** {@inheritDoc} */ public Result get(byte[] regionName, Get get) throws IOException { checkOpen(); diff --git src/main/java/org/apache/hadoop/hbase/regionserver/MemStore.java src/main/java/org/apache/hadoop/hbase/regionserver/MemStore.java index 0592f40..08c346a 100644 --- src/main/java/org/apache/hadoop/hbase/regionserver/MemStore.java +++ src/main/java/org/apache/hadoop/hbase/regionserver/MemStore.java @@ -354,88 +354,6 @@ public class MemStore implements HeapSize { } /** - * @param state column/delete tracking state - */ - void getRowKeyAtOrBefore(final GetClosestRowBeforeTracker state) { - this.lock.readLock().lock(); - try { - getRowKeyAtOrBefore(kvset, state); - getRowKeyAtOrBefore(snapshot, state); - } finally { - this.lock.readLock().unlock(); - } - } - - /* - * @param set - * @param state Accumulates deletes and candidates. - */ - private void getRowKeyAtOrBefore(final NavigableSet set, - final GetClosestRowBeforeTracker state) { - if (set.isEmpty()) { - return; - } - if (!walkForwardInSingleRow(set, state.getTargetKey(), state)) { - // Found nothing in row. Try backing up. - getRowKeyBefore(set, state); - } - } - - /* - * Walk forward in a row from firstOnRow. Presumption is that - * we have been passed the first possible key on a row. As we walk forward - * we accumulate deletes until we hit a candidate on the row at which point - * we return. - * @param set - * @param firstOnRow First possible key on this row. - * @param state - * @return True if we found a candidate walking this row. - */ - private boolean walkForwardInSingleRow(final SortedSet set, - final KeyValue firstOnRow, final GetClosestRowBeforeTracker state) { - boolean foundCandidate = false; - SortedSet tail = set.tailSet(firstOnRow); - if (tail.isEmpty()) return foundCandidate; - for (Iterator i = tail.iterator(); i.hasNext();) { - KeyValue kv = i.next(); - // Did we go beyond the target row? If so break. - if (state.isTooFar(kv, firstOnRow)) break; - if (state.isExpired(kv)) { - i.remove(); - continue; - } - // If we added something, this row is a contender. break. - if (state.handle(kv)) { - foundCandidate = true; - break; - } - } - return foundCandidate; - } - - /* - * Walk backwards through the passed set a row at a time until we run out of - * set or until we get a candidate. - * @param set - * @param state - */ - private void getRowKeyBefore(NavigableSet set, - final GetClosestRowBeforeTracker state) { - KeyValue firstOnRow = state.getTargetKey(); - for (Member p = memberOfPreviousRow(set, state, firstOnRow); - p != null; p = memberOfPreviousRow(p.set, state, firstOnRow)) { - // Make sure we don't fall out of our table. - if (!state.isTargetTable(p.kv)) break; - // Stop looking if we've exited the better candidate range. - if (!state.isBetterCandidate(p.kv)) break; - // Make into firstOnRow - firstOnRow = new KeyValue(p.kv.getRow(), HConstants.LATEST_TIMESTAMP); - // If we find something, break; - if (walkForwardInSingleRow(p.set, firstOnRow, state)) break; - } - } - - /** * Given the specs of a column, update it, first by inserting a new record, * then removing the old one. Since there is only 1 KeyValue involved, the memstoreTS * will be set to 0, thus ensuring that they instantly appear to anyone. The underlying @@ -610,29 +528,6 @@ public class MemStore implements HeapSize { } } - /* - * @param set Set to walk back in. Pass a first in row or we'll return - * same row (loop). - * @param state Utility and context. - * @param firstOnRow First item on the row after the one we want to find a - * member in. - * @return Null or member of row previous to firstOnRow - */ - private Member memberOfPreviousRow(NavigableSet set, - final GetClosestRowBeforeTracker state, final KeyValue firstOnRow) { - NavigableSet head = set.headSet(firstOnRow, false); - if (head.isEmpty()) return null; - for (Iterator i = head.descendingIterator(); i.hasNext();) { - KeyValue found = i.next(); - if (state.isExpired(found)) { - i.remove(); - continue; - } - return new Member(head, found); - } - return null; - } - /** * @return scanner on memstore and snapshot in this order. */ diff --git src/main/java/org/apache/hadoop/hbase/regionserver/RegionCoprocessorHost.java src/main/java/org/apache/hadoop/hbase/regionserver/RegionCoprocessorHost.java index a3850e5..34143a4 100644 --- src/main/java/org/apache/hadoop/hbase/regionserver/RegionCoprocessorHost.java +++ src/main/java/org/apache/hadoop/hbase/regionserver/RegionCoprocessorHost.java @@ -484,60 +484,6 @@ public class RegionCoprocessorHost // RegionObserver support /** - * @param row the row key - * @param family the family - * @param result the result set from the region - * @return true if default processing should be bypassed - * @exception IOException Exception - */ - public boolean preGetClosestRowBefore(final byte[] row, final byte[] family, - final Result result) throws IOException { - boolean bypass = false; - ObserverContext ctx = null; - for (RegionEnvironment env: coprocessors) { - if (env.getInstance() instanceof RegionObserver) { - ctx = ObserverContext.createAndPrepare(env, ctx); - try { - ((RegionObserver)env.getInstance()).preGetClosestRowBefore(ctx, row, - family, result); - } catch (Throwable e) { - handleCoprocessorThrowable(env, e); - } - bypass |= ctx.shouldBypass(); - if (ctx.shouldComplete()) { - break; - } - } - } - return bypass; - } - - /** - * @param row the row key - * @param family the family - * @param result the result set from the region - * @exception IOException Exception - */ - public void postGetClosestRowBefore(final byte[] row, final byte[] family, - final Result result) throws IOException { - ObserverContext ctx = null; - for (RegionEnvironment env: coprocessors) { - if (env.getInstance() instanceof RegionObserver) { - ctx = ObserverContext.createAndPrepare(env, ctx); - try { - ((RegionObserver)env.getInstance()).postGetClosestRowBefore(ctx, row, - family, result); - } catch (Throwable e) { - handleCoprocessorThrowable(env, e); - } - if (ctx.shouldComplete()) { - break; - } - } - } - } - - /** * @param get the Get request * @return true if default processing should be bypassed * @exception IOException Exception diff --git src/main/java/org/apache/hadoop/hbase/regionserver/Store.java src/main/java/org/apache/hadoop/hbase/regionserver/Store.java index 0c7b396..eaca508 100644 --- src/main/java/org/apache/hadoop/hbase/regionserver/Store.java +++ src/main/java/org/apache/hadoop/hbase/regionserver/Store.java @@ -1623,99 +1623,6 @@ public class Store extends SchemaConfigured implements HeapSize { return key.getTimestamp() < oldestTimestamp; } - /** - * Find the key that matches row exactly, or the one that immediately - * precedes it. WARNING: Only use this method on a table where writes occur - * with strictly increasing timestamps. This method assumes this pattern of - * writes in order to make it reasonably performant. Also our search is - * dependent on the axiom that deletes are for cells that are in the container - * that follows whether a memstore snapshot or a storefile, not for the - * current container: i.e. we'll see deletes before we come across cells we - * are to delete. Presumption is that the memstore#kvset is processed before - * memstore#snapshot and so on. - * @param row The row key of the targeted row. - * @return Found keyvalue or null if none found. - * @throws IOException - */ - KeyValue getRowKeyAtOrBefore(final byte[] row) throws IOException { - // If minVersions is set, we will not ignore expired KVs. - // As we're only looking for the latest matches, that should be OK. - // With minVersions > 0 we guarantee that any KV that has any version - // at all (expired or not) has at least one version that will not expire. - // Note that this method used to take a KeyValue as arguments. KeyValue - // can be back-dated, a row key cannot. - long ttlToUse = scanInfo.getMinVersions() > 0 ? Long.MAX_VALUE : this.ttl; - - KeyValue kv = new KeyValue(row, HConstants.LATEST_TIMESTAMP); - - GetClosestRowBeforeTracker state = new GetClosestRowBeforeTracker( - this.comparator, kv, ttlToUse, this.region.getRegionInfo().isMetaRegion()); - this.lock.readLock().lock(); - try { - // First go to the memstore. Pick up deletes and candidates. - this.memstore.getRowKeyAtOrBefore(state); - // Check if match, if we got a candidate on the asked for 'kv' row. - // Process each store file. Run through from newest to oldest. - for (StoreFile sf : Lists.reverse(storefiles)) { - // Update the candidate keys from the current map file - rowAtOrBeforeFromStoreFile(sf, state); - } - return state.getCandidate(); - } finally { - this.lock.readLock().unlock(); - } - } - - /* - * Check an individual MapFile for the row at or before a given row. - * @param f - * @param state - * @throws IOException - */ - private void rowAtOrBeforeFromStoreFile(final StoreFile f, - final GetClosestRowBeforeTracker state) - throws IOException { - StoreFile.Reader r = f.getReader(); - if (r == null) { - LOG.warn("StoreFile " + f + " has a null Reader"); - return; - } - // TODO: Cache these keys rather than make each time? - byte [] fk = r.getFirstKey(); - KeyValue firstKV = KeyValue.createKeyValueFromKey(fk, 0, fk.length); - byte [] lk = r.getLastKey(); - KeyValue lastKV = KeyValue.createKeyValueFromKey(lk, 0, lk.length); - KeyValue firstOnRow = state.getTargetKey(); - if (this.comparator.compareRows(lastKV, firstOnRow) < 0) { - // If last key in file is not of the target table, no candidates in this - // file. Return. - if (!state.isTargetTable(lastKV)) return; - // If the row we're looking for is past the end of file, set search key to - // last key. TODO: Cache last and first key rather than make each time. - firstOnRow = new KeyValue(lastKV.getRow(), HConstants.LATEST_TIMESTAMP); - } - // Get a scanner that caches blocks and that uses pread. - HFileScanner scanner = r.getHFileReader().getScanner(true, true, false); - // Seek scanner. If can't seek it, return. - if (!seekToScanner(scanner, firstOnRow, firstKV)) return; - // If we found candidate on firstOnRow, just return. THIS WILL NEVER HAPPEN! - // Unlikely that there'll be an instance of actual first row in table. - if (walkForwardInSingleRow(scanner, firstOnRow, state)) return; - // If here, need to start backing up. - while (scanner.seekBefore(firstOnRow.getBuffer(), firstOnRow.getKeyOffset(), - firstOnRow.getKeyLength())) { - KeyValue kv = scanner.getKeyValue(); - if (!state.isTargetTable(kv)) break; - if (!state.isBetterCandidate(kv)) break; - // Make new first on row. - firstOnRow = new KeyValue(kv.getRow(), HConstants.LATEST_TIMESTAMP); - // Seek scanner. If can't seek it, break. - if (!seekToScanner(scanner, firstOnRow, firstKV)) break; - // If we find something, break; - if (walkForwardInSingleRow(scanner, firstOnRow, state)) break; - } - } - /* * Seek the file scanner to firstOnRow or first entry in file. * @param scanner @@ -1736,39 +1643,6 @@ public class Store extends SchemaConfigured implements HeapSize { return result >= 0; } - /* - * When we come in here, we are probably at the kv just before we break into - * the row that firstOnRow is on. Usually need to increment one time to get - * on to the row we are interested in. - * @param scanner - * @param firstOnRow - * @param state - * @return True we found a candidate. - * @throws IOException - */ - private boolean walkForwardInSingleRow(final HFileScanner scanner, - final KeyValue firstOnRow, - final GetClosestRowBeforeTracker state) - throws IOException { - boolean foundCandidate = false; - do { - KeyValue kv = scanner.getKeyValue(); - // If we are not in the row, skip. - if (this.comparator.compareRows(kv, firstOnRow) < 0) continue; - // Did we go beyond the target row? If so break. - if (state.isTooFar(kv, firstOnRow)) break; - if (state.isExpired(kv)) { - continue; - } - // If we added something, this row is a contender. break. - if (state.handle(kv)) { - foundCandidate = true; - break; - } - } while(scanner.next()); - return foundCandidate; - } - public boolean canSplit() { this.lock.readLock().lock(); try { diff --git src/main/java/org/apache/hadoop/hbase/rest/StorageClusterStatusResource.java src/main/java/org/apache/hadoop/hbase/rest/StorageClusterStatusResource.java index 59a791d..67f2c2d 100644 --- src/main/java/org/apache/hadoop/hbase/rest/StorageClusterStatusResource.java +++ src/main/java/org/apache/hadoop/hbase/rest/StorageClusterStatusResource.java @@ -87,11 +87,7 @@ public class StorageClusterStatusResource extends ResourceBase { for (HServerLoad.RegionLoad region: load.getRegionsLoad().values()) { node.addRegion(region.getName(), region.getStores(), region.getStorefiles(), region.getStorefileSizeMB(), - region.getMemStoreSizeMB(), region.getStorefileIndexSizeMB(), - region.getReadRequestsCount(), region.getWriteRequestsCount(), - region.getRootIndexSizeKB(), region.getTotalStaticIndexSizeKB(), - region.getTotalStaticBloomSizeKB(), region.getTotalCompactingKVs(), - region.getCurrentCompactedKVs()); + region.getMemStoreSizeMB(), region.getStorefileIndexSizeMB()); } } for (ServerName name: status.getDeadServerNames()) { diff --git src/main/java/org/apache/hadoop/hbase/rest/client/RemoteHTable.java src/main/java/org/apache/hadoop/hbase/rest/client/RemoteHTable.java index 56e31e1..2ecdce8 100644 --- src/main/java/org/apache/hadoop/hbase/rest/client/RemoteHTable.java +++ src/main/java/org/apache/hadoop/hbase/rest/client/RemoteHTable.java @@ -575,10 +575,6 @@ public class RemoteHTable implements HTableInterface { return true; } - public Result getRowOrBefore(byte[] row, byte[] family) throws IOException { - throw new IOException("getRowOrBefore not supported"); - } - public RowLock lockRow(byte[] row) throws IOException { throw new IOException("lockRow not implemented"); } diff --git src/main/java/org/apache/hadoop/hbase/rest/model/StorageClusterStatusModel.java src/main/java/org/apache/hadoop/hbase/rest/model/StorageClusterStatusModel.java index 5072221..2ce6133 100644 --- src/main/java/org/apache/hadoop/hbase/rest/model/StorageClusterStatusModel.java +++ src/main/java/org/apache/hadoop/hbase/rest/model/StorageClusterStatusModel.java @@ -83,13 +83,6 @@ import com.google.protobuf.ByteString; * <attribute name="storefileSizeMB" type="int"></attribute> * <attribute name="memstoreSizeMB" type="int"></attribute> * <attribute name="storefileIndexSizeMB" type="int"></attribute> - * <attribute name="readRequestsCount" type="int"></attribute> - * <attribute name="writeRequestsCount" type="int"></attribute> - * <attribute name="rootIndexSizeKB" type="int"></attribute> - * <attribute name="totalStaticIndexSizeKB" type="int"></attribute> - * <attribute name="totalStaticBloomSizeKB" type="int"></attribute> - * <attribute name="totalCompactingKVs" type="int"></attribute> - * <attribute name="currentCompactedKVs" type="int"></attribute> * </complexType> * */ @@ -114,13 +107,6 @@ public class StorageClusterStatusModel private int storefileSizeMB; private int memstoreSizeMB; private int storefileIndexSizeMB; - private long readRequestsCount; - private long writeRequestsCount; - private int rootIndexSizeKB; - private int totalStaticIndexSizeKB; - private int totalStaticBloomSizeKB; - private long totalCompactingKVs; - private long currentCompactedKVs; /** * Default constructor @@ -145,23 +131,13 @@ public class StorageClusterStatusModel * @param storefileIndexSizeMB total size of store file indexes, in MB */ public Region(byte[] name, int stores, int storefiles, - int storefileSizeMB, int memstoreSizeMB, int storefileIndexSizeMB, - long readRequestsCount, long writeRequestsCount, int rootIndexSizeKB, - int totalStaticIndexSizeKB, int totalStaticBloomSizeKB, - long totalCompactingKVs, long currentCompactedKVs) { + int storefileSizeMB, int memstoreSizeMB, int storefileIndexSizeMB) { this.name = name; this.stores = stores; this.storefiles = storefiles; this.storefileSizeMB = storefileSizeMB; this.memstoreSizeMB = memstoreSizeMB; this.storefileIndexSizeMB = storefileIndexSizeMB; - this.readRequestsCount = readRequestsCount; - this.writeRequestsCount = writeRequestsCount; - this.rootIndexSizeKB = rootIndexSizeKB; - this.totalStaticIndexSizeKB = totalStaticIndexSizeKB; - this.totalStaticBloomSizeKB = totalStaticBloomSizeKB; - this.totalCompactingKVs = totalCompactingKVs; - this.currentCompactedKVs = currentCompactedKVs; } /** @@ -211,118 +187,8 @@ public class StorageClusterStatusModel public int getStorefileIndexSizeMB() { return storefileIndexSizeMB; } - - /** - * @return the current total read requests made to region - */ - @XmlAttribute - public long getReadRequestsCount() { - return readRequestsCount; - } - - /** - * @return the current total write requests made to region - */ - @XmlAttribute - public long getWriteRequestsCount() { - return writeRequestsCount; - } - - /** - * @return The current total size of root-level indexes for the region, in KB. - */ - @XmlAttribute - public int getRootIndexSizeKB() { - return rootIndexSizeKB; - } - - /** - * @return The total size of static index, in KB - */ - @XmlAttribute - public int getTotalStaticIndexSizeKB() { - return totalStaticIndexSizeKB; - } - - /** - * @return The total size of static bloom, in KB - */ - @XmlAttribute - public int getTotalStaticBloomSizeKB() { - return totalStaticBloomSizeKB; - } - - /** - * @return The total number of compacting key-values - */ - @XmlAttribute - public long getTotalCompactingKVs() { - return totalCompactingKVs; - } /** - * @return The number of current compacted key-values - */ - @XmlAttribute - public long getCurrentCompactedKVs() { - return currentCompactedKVs; - } - - /** - * @param readRequestsCount The current total read requests made to region - */ - public void setReadRequestsCount(long readRequestsCount) { - this.readRequestsCount = readRequestsCount; - } - - /** - * @param rootIndexSizeKB The current total size of root-level indexes - * for the region, in KB - */ - public void setRootIndexSizeKB(int rootIndexSizeKB) { - this.rootIndexSizeKB = rootIndexSizeKB; - } - - /** - * @param writeRequestsCount The current total write requests made to region - */ - public void setWriteRequestsCount(long writeRequestsCount) { - this.writeRequestsCount = writeRequestsCount; - } - - /** - * @param currentCompactedKVs The completed count of key values - * in currently running compaction - */ - public void setCurrentCompactedKVs(long currentCompactedKVs) { - this.currentCompactedKVs = currentCompactedKVs; - } - - /** - * @param totalCompactingKVs The total compacting key values - * in currently running compaction - */ - public void setTotalCompactingKVs(long totalCompactingKVs) { - this.totalCompactingKVs = totalCompactingKVs; - } - - /** - * @param totalStaticBloomSizeKB The total size of all Bloom filter blocks, - * not just loaded into the block cache, in KB. - */ - public void setTotalStaticBloomSizeKB(int totalStaticBloomSizeKB) { - this.totalStaticBloomSizeKB = totalStaticBloomSizeKB; - } - - /** - * @param totalStaticIndexSizeKB The total size of all index blocks, - * not just the root level, in KB. - */ - public void setTotalStaticIndexSizeKB(int totalStaticIndexSizeKB) { - this.totalStaticIndexSizeKB = totalStaticIndexSizeKB; - } - - /** * @param name the region name */ public void setName(byte[] name) { @@ -377,14 +243,9 @@ public class StorageClusterStatusModel * @param name the region name */ public void addRegion(byte[] name, int stores, int storefiles, - int storefileSizeMB, int memstoreSizeMB, int storefileIndexSizeMB, - long readRequestsCount, long writeRequestsCount, int rootIndexSizeKB, - int totalStaticIndexSizeKB, int totalStaticBloomSizeKB, - long totalCompactingKVs, long currentCompactedKVs) { + int storefileSizeMB, int memstoreSizeMB, int storefileIndexSizeMB) { regions.add(new Region(name, stores, storefiles, storefileSizeMB, - memstoreSizeMB, storefileIndexSizeMB, readRequestsCount, - writeRequestsCount, rootIndexSizeKB, totalStaticIndexSizeKB, - totalStaticBloomSizeKB, totalCompactingKVs, currentCompactedKVs)); + memstoreSizeMB, storefileIndexSizeMB)); } /** @@ -671,20 +532,6 @@ public class StorageClusterStatusModel sb.append(region.memstoreSizeMB); sb.append("\n storefileIndexSizeMB="); sb.append(region.storefileIndexSizeMB); - sb.append("\n readRequestsCount="); - sb.append(region.readRequestsCount); - sb.append("\n writeRequestsCount="); - sb.append(region.writeRequestsCount); - sb.append("\n rootIndexSizeKB="); - sb.append(region.rootIndexSizeKB); - sb.append("\n totalStaticIndexSizeKB="); - sb.append(region.totalStaticIndexSizeKB); - sb.append("\n totalStaticBloomSizeKB="); - sb.append(region.totalStaticBloomSizeKB); - sb.append("\n totalCompactingKVs="); - sb.append(region.totalCompactingKVs); - sb.append("\n currentCompactedKVs="); - sb.append(region.currentCompactedKVs); sb.append('\n'); } sb.append('\n'); @@ -702,7 +549,7 @@ public class StorageClusterStatusModel } return sb.toString(); } - + @Override public byte[] createProtobufOutput() { StorageClusterStatus.Builder builder = StorageClusterStatus.newBuilder(); @@ -726,13 +573,6 @@ public class StorageClusterStatusModel regionBuilder.setStorefileSizeMB(region.storefileSizeMB); regionBuilder.setMemstoreSizeMB(region.memstoreSizeMB); regionBuilder.setStorefileIndexSizeMB(region.storefileIndexSizeMB); - regionBuilder.setReadRequestsCount(region.readRequestsCount); - regionBuilder.setWriteRequestsCount(region.writeRequestsCount); - regionBuilder.setRootIndexSizeKB(region.rootIndexSizeKB); - regionBuilder.setTotalStaticIndexSizeKB(region.totalStaticIndexSizeKB); - regionBuilder.setTotalStaticBloomSizeKB(region.totalStaticBloomSizeKB); - regionBuilder.setTotalCompactingKVs(region.totalCompactingKVs); - regionBuilder.setCurrentCompactedKVs(region.currentCompactedKVs); nodeBuilder.addRegions(regionBuilder); } builder.addLiveNodes(nodeBuilder); @@ -771,14 +611,7 @@ public class StorageClusterStatusModel region.getStorefiles(), region.getStorefileSizeMB(), region.getMemstoreSizeMB(), - region.getStorefileIndexSizeMB(), - region.getReadRequestsCount(), - region.getWriteRequestsCount(), - region.getRootIndexSizeKB(), - region.getTotalStaticIndexSizeKB(), - region.getTotalStaticBloomSizeKB(), - region.getTotalCompactingKVs(), - region.getCurrentCompactedKVs()); + region.getStorefileIndexSizeMB()); } } for (String node: builder.getDeadNodesList()) { 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 3535595..9e16272 100644 --- src/main/java/org/apache/hadoop/hbase/rest/model/TableRegionModel.java +++ src/main/java/org/apache/hadoop/hbase/rest/model/TableRegionModel.java @@ -97,9 +97,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); } /** @@ -111,6 +113,14 @@ public class TableRegionModel implements Serializable { } /** + * @return the table name + */ + @XmlAttribute + public String getTable() { + return table; + } + + /** * @return the start key */ @XmlAttribute @@ -135,15 +145,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; } /** @@ -187,6 +192,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/main/java/org/apache/hadoop/hbase/rest/protobuf/generated/StorageClusterStatusMessage.java src/main/java/org/apache/hadoop/hbase/rest/protobuf/generated/StorageClusterStatusMessage.java index a6023b9..b20d6d4 100644 --- src/main/java/org/apache/hadoop/hbase/rest/protobuf/generated/StorageClusterStatusMessage.java +++ src/main/java/org/apache/hadoop/hbase/rest/protobuf/generated/StorageClusterStatusMessage.java @@ -92,34 +92,6 @@ public final class StorageClusterStatusMessage { // optional int32 storefileIndexSizeMB = 6; boolean hasStorefileIndexSizeMB(); int getStorefileIndexSizeMB(); - - // optional int64 readRequestsCount = 7; - boolean hasReadRequestsCount(); - long getReadRequestsCount(); - - // optional int64 writeRequestsCount = 8; - boolean hasWriteRequestsCount(); - long getWriteRequestsCount(); - - // optional int32 rootIndexSizeKB = 9; - boolean hasRootIndexSizeKB(); - int getRootIndexSizeKB(); - - // optional int32 totalStaticIndexSizeKB = 10; - boolean hasTotalStaticIndexSizeKB(); - int getTotalStaticIndexSizeKB(); - - // optional int32 totalStaticBloomSizeKB = 11; - boolean hasTotalStaticBloomSizeKB(); - int getTotalStaticBloomSizeKB(); - - // optional int64 totalCompactingKVs = 12; - boolean hasTotalCompactingKVs(); - long getTotalCompactingKVs(); - - // optional int64 currentCompactedKVs = 13; - boolean hasCurrentCompactedKVs(); - long getCurrentCompactedKVs(); } public static final class Region extends com.google.protobuf.GeneratedMessage @@ -210,76 +182,6 @@ public final class StorageClusterStatusMessage { return storefileIndexSizeMB_; } - // optional int64 readRequestsCount = 7; - public static final int READREQUESTSCOUNT_FIELD_NUMBER = 7; - private long readRequestsCount_; - public boolean hasReadRequestsCount() { - return ((bitField0_ & 0x00000040) == 0x00000040); - } - public long getReadRequestsCount() { - return readRequestsCount_; - } - - // optional int64 writeRequestsCount = 8; - public static final int WRITEREQUESTSCOUNT_FIELD_NUMBER = 8; - private long writeRequestsCount_; - public boolean hasWriteRequestsCount() { - return ((bitField0_ & 0x00000080) == 0x00000080); - } - public long getWriteRequestsCount() { - return writeRequestsCount_; - } - - // optional int32 rootIndexSizeKB = 9; - public static final int ROOTINDEXSIZEKB_FIELD_NUMBER = 9; - private int rootIndexSizeKB_; - public boolean hasRootIndexSizeKB() { - return ((bitField0_ & 0x00000100) == 0x00000100); - } - public int getRootIndexSizeKB() { - return rootIndexSizeKB_; - } - - // optional int32 totalStaticIndexSizeKB = 10; - public static final int TOTALSTATICINDEXSIZEKB_FIELD_NUMBER = 10; - private int totalStaticIndexSizeKB_; - public boolean hasTotalStaticIndexSizeKB() { - return ((bitField0_ & 0x00000200) == 0x00000200); - } - public int getTotalStaticIndexSizeKB() { - return totalStaticIndexSizeKB_; - } - - // optional int32 totalStaticBloomSizeKB = 11; - public static final int TOTALSTATICBLOOMSIZEKB_FIELD_NUMBER = 11; - private int totalStaticBloomSizeKB_; - public boolean hasTotalStaticBloomSizeKB() { - return ((bitField0_ & 0x00000400) == 0x00000400); - } - public int getTotalStaticBloomSizeKB() { - return totalStaticBloomSizeKB_; - } - - // optional int64 totalCompactingKVs = 12; - public static final int TOTALCOMPACTINGKVS_FIELD_NUMBER = 12; - private long totalCompactingKVs_; - public boolean hasTotalCompactingKVs() { - return ((bitField0_ & 0x00000800) == 0x00000800); - } - public long getTotalCompactingKVs() { - return totalCompactingKVs_; - } - - // optional int64 currentCompactedKVs = 13; - public static final int CURRENTCOMPACTEDKVS_FIELD_NUMBER = 13; - private long currentCompactedKVs_; - public boolean hasCurrentCompactedKVs() { - return ((bitField0_ & 0x00001000) == 0x00001000); - } - public long getCurrentCompactedKVs() { - return currentCompactedKVs_; - } - private void initFields() { name_ = com.google.protobuf.ByteString.EMPTY; stores_ = 0; @@ -287,13 +189,6 @@ public final class StorageClusterStatusMessage { storefileSizeMB_ = 0; memstoreSizeMB_ = 0; storefileIndexSizeMB_ = 0; - readRequestsCount_ = 0L; - writeRequestsCount_ = 0L; - rootIndexSizeKB_ = 0; - totalStaticIndexSizeKB_ = 0; - totalStaticBloomSizeKB_ = 0; - totalCompactingKVs_ = 0L; - currentCompactedKVs_ = 0L; } private byte memoizedIsInitialized = -1; public final boolean isInitialized() { @@ -329,27 +224,6 @@ public final class StorageClusterStatusMessage { if (((bitField0_ & 0x00000020) == 0x00000020)) { output.writeInt32(6, storefileIndexSizeMB_); } - if (((bitField0_ & 0x00000040) == 0x00000040)) { - output.writeInt64(7, readRequestsCount_); - } - if (((bitField0_ & 0x00000080) == 0x00000080)) { - output.writeInt64(8, writeRequestsCount_); - } - if (((bitField0_ & 0x00000100) == 0x00000100)) { - output.writeInt32(9, rootIndexSizeKB_); - } - if (((bitField0_ & 0x00000200) == 0x00000200)) { - output.writeInt32(10, totalStaticIndexSizeKB_); - } - if (((bitField0_ & 0x00000400) == 0x00000400)) { - output.writeInt32(11, totalStaticBloomSizeKB_); - } - if (((bitField0_ & 0x00000800) == 0x00000800)) { - output.writeInt64(12, totalCompactingKVs_); - } - if (((bitField0_ & 0x00001000) == 0x00001000)) { - output.writeInt64(13, currentCompactedKVs_); - } getUnknownFields().writeTo(output); } @@ -383,34 +257,6 @@ public final class StorageClusterStatusMessage { size += com.google.protobuf.CodedOutputStream .computeInt32Size(6, storefileIndexSizeMB_); } - if (((bitField0_ & 0x00000040) == 0x00000040)) { - size += com.google.protobuf.CodedOutputStream - .computeInt64Size(7, readRequestsCount_); - } - if (((bitField0_ & 0x00000080) == 0x00000080)) { - size += com.google.protobuf.CodedOutputStream - .computeInt64Size(8, writeRequestsCount_); - } - if (((bitField0_ & 0x00000100) == 0x00000100)) { - size += com.google.protobuf.CodedOutputStream - .computeInt32Size(9, rootIndexSizeKB_); - } - if (((bitField0_ & 0x00000200) == 0x00000200)) { - size += com.google.protobuf.CodedOutputStream - .computeInt32Size(10, totalStaticIndexSizeKB_); - } - if (((bitField0_ & 0x00000400) == 0x00000400)) { - size += com.google.protobuf.CodedOutputStream - .computeInt32Size(11, totalStaticBloomSizeKB_); - } - if (((bitField0_ & 0x00000800) == 0x00000800)) { - size += com.google.protobuf.CodedOutputStream - .computeInt64Size(12, totalCompactingKVs_); - } - if (((bitField0_ & 0x00001000) == 0x00001000)) { - size += com.google.protobuf.CodedOutputStream - .computeInt64Size(13, currentCompactedKVs_); - } size += getUnknownFields().getSerializedSize(); memoizedSerializedSize = size; return size; @@ -547,20 +393,6 @@ public final class StorageClusterStatusMessage { bitField0_ = (bitField0_ & ~0x00000010); storefileIndexSizeMB_ = 0; bitField0_ = (bitField0_ & ~0x00000020); - readRequestsCount_ = 0L; - bitField0_ = (bitField0_ & ~0x00000040); - writeRequestsCount_ = 0L; - bitField0_ = (bitField0_ & ~0x00000080); - rootIndexSizeKB_ = 0; - bitField0_ = (bitField0_ & ~0x00000100); - totalStaticIndexSizeKB_ = 0; - bitField0_ = (bitField0_ & ~0x00000200); - totalStaticBloomSizeKB_ = 0; - bitField0_ = (bitField0_ & ~0x00000400); - totalCompactingKVs_ = 0L; - bitField0_ = (bitField0_ & ~0x00000800); - currentCompactedKVs_ = 0L; - bitField0_ = (bitField0_ & ~0x00001000); return this; } @@ -623,34 +455,6 @@ public final class StorageClusterStatusMessage { to_bitField0_ |= 0x00000020; } result.storefileIndexSizeMB_ = storefileIndexSizeMB_; - if (((from_bitField0_ & 0x00000040) == 0x00000040)) { - to_bitField0_ |= 0x00000040; - } - result.readRequestsCount_ = readRequestsCount_; - if (((from_bitField0_ & 0x00000080) == 0x00000080)) { - to_bitField0_ |= 0x00000080; - } - result.writeRequestsCount_ = writeRequestsCount_; - if (((from_bitField0_ & 0x00000100) == 0x00000100)) { - to_bitField0_ |= 0x00000100; - } - result.rootIndexSizeKB_ = rootIndexSizeKB_; - if (((from_bitField0_ & 0x00000200) == 0x00000200)) { - to_bitField0_ |= 0x00000200; - } - result.totalStaticIndexSizeKB_ = totalStaticIndexSizeKB_; - if (((from_bitField0_ & 0x00000400) == 0x00000400)) { - to_bitField0_ |= 0x00000400; - } - result.totalStaticBloomSizeKB_ = totalStaticBloomSizeKB_; - if (((from_bitField0_ & 0x00000800) == 0x00000800)) { - to_bitField0_ |= 0x00000800; - } - result.totalCompactingKVs_ = totalCompactingKVs_; - if (((from_bitField0_ & 0x00001000) == 0x00001000)) { - to_bitField0_ |= 0x00001000; - } - result.currentCompactedKVs_ = currentCompactedKVs_; result.bitField0_ = to_bitField0_; onBuilt(); return result; @@ -685,27 +489,6 @@ public final class StorageClusterStatusMessage { if (other.hasStorefileIndexSizeMB()) { setStorefileIndexSizeMB(other.getStorefileIndexSizeMB()); } - if (other.hasReadRequestsCount()) { - setReadRequestsCount(other.getReadRequestsCount()); - } - if (other.hasWriteRequestsCount()) { - setWriteRequestsCount(other.getWriteRequestsCount()); - } - if (other.hasRootIndexSizeKB()) { - setRootIndexSizeKB(other.getRootIndexSizeKB()); - } - if (other.hasTotalStaticIndexSizeKB()) { - setTotalStaticIndexSizeKB(other.getTotalStaticIndexSizeKB()); - } - if (other.hasTotalStaticBloomSizeKB()) { - setTotalStaticBloomSizeKB(other.getTotalStaticBloomSizeKB()); - } - if (other.hasTotalCompactingKVs()) { - setTotalCompactingKVs(other.getTotalCompactingKVs()); - } - if (other.hasCurrentCompactedKVs()) { - setCurrentCompactedKVs(other.getCurrentCompactedKVs()); - } this.mergeUnknownFields(other.getUnknownFields()); return this; } @@ -771,41 +554,6 @@ public final class StorageClusterStatusMessage { storefileIndexSizeMB_ = input.readInt32(); break; } - case 56: { - bitField0_ |= 0x00000040; - readRequestsCount_ = input.readInt64(); - break; - } - case 64: { - bitField0_ |= 0x00000080; - writeRequestsCount_ = input.readInt64(); - break; - } - case 72: { - bitField0_ |= 0x00000100; - rootIndexSizeKB_ = input.readInt32(); - break; - } - case 80: { - bitField0_ |= 0x00000200; - totalStaticIndexSizeKB_ = input.readInt32(); - break; - } - case 88: { - bitField0_ |= 0x00000400; - totalStaticBloomSizeKB_ = input.readInt32(); - break; - } - case 96: { - bitField0_ |= 0x00000800; - totalCompactingKVs_ = input.readInt64(); - break; - } - case 104: { - bitField0_ |= 0x00001000; - currentCompactedKVs_ = input.readInt64(); - break; - } } } } @@ -941,153 +689,6 @@ public final class StorageClusterStatusMessage { return this; } - // optional int64 readRequestsCount = 7; - private long readRequestsCount_ ; - public boolean hasReadRequestsCount() { - return ((bitField0_ & 0x00000040) == 0x00000040); - } - public long getReadRequestsCount() { - return readRequestsCount_; - } - public Builder setReadRequestsCount(long value) { - bitField0_ |= 0x00000040; - readRequestsCount_ = value; - onChanged(); - return this; - } - public Builder clearReadRequestsCount() { - bitField0_ = (bitField0_ & ~0x00000040); - readRequestsCount_ = 0L; - onChanged(); - return this; - } - - // optional int64 writeRequestsCount = 8; - private long writeRequestsCount_ ; - public boolean hasWriteRequestsCount() { - return ((bitField0_ & 0x00000080) == 0x00000080); - } - public long getWriteRequestsCount() { - return writeRequestsCount_; - } - public Builder setWriteRequestsCount(long value) { - bitField0_ |= 0x00000080; - writeRequestsCount_ = value; - onChanged(); - return this; - } - public Builder clearWriteRequestsCount() { - bitField0_ = (bitField0_ & ~0x00000080); - writeRequestsCount_ = 0L; - onChanged(); - return this; - } - - // optional int32 rootIndexSizeKB = 9; - private int rootIndexSizeKB_ ; - public boolean hasRootIndexSizeKB() { - return ((bitField0_ & 0x00000100) == 0x00000100); - } - public int getRootIndexSizeKB() { - return rootIndexSizeKB_; - } - public Builder setRootIndexSizeKB(int value) { - bitField0_ |= 0x00000100; - rootIndexSizeKB_ = value; - onChanged(); - return this; - } - public Builder clearRootIndexSizeKB() { - bitField0_ = (bitField0_ & ~0x00000100); - rootIndexSizeKB_ = 0; - onChanged(); - return this; - } - - // optional int32 totalStaticIndexSizeKB = 10; - private int totalStaticIndexSizeKB_ ; - public boolean hasTotalStaticIndexSizeKB() { - return ((bitField0_ & 0x00000200) == 0x00000200); - } - public int getTotalStaticIndexSizeKB() { - return totalStaticIndexSizeKB_; - } - public Builder setTotalStaticIndexSizeKB(int value) { - bitField0_ |= 0x00000200; - totalStaticIndexSizeKB_ = value; - onChanged(); - return this; - } - public Builder clearTotalStaticIndexSizeKB() { - bitField0_ = (bitField0_ & ~0x00000200); - totalStaticIndexSizeKB_ = 0; - onChanged(); - return this; - } - - // optional int32 totalStaticBloomSizeKB = 11; - private int totalStaticBloomSizeKB_ ; - public boolean hasTotalStaticBloomSizeKB() { - return ((bitField0_ & 0x00000400) == 0x00000400); - } - public int getTotalStaticBloomSizeKB() { - return totalStaticBloomSizeKB_; - } - public Builder setTotalStaticBloomSizeKB(int value) { - bitField0_ |= 0x00000400; - totalStaticBloomSizeKB_ = value; - onChanged(); - return this; - } - public Builder clearTotalStaticBloomSizeKB() { - bitField0_ = (bitField0_ & ~0x00000400); - totalStaticBloomSizeKB_ = 0; - onChanged(); - return this; - } - - // optional int64 totalCompactingKVs = 12; - private long totalCompactingKVs_ ; - public boolean hasTotalCompactingKVs() { - return ((bitField0_ & 0x00000800) == 0x00000800); - } - public long getTotalCompactingKVs() { - return totalCompactingKVs_; - } - public Builder setTotalCompactingKVs(long value) { - bitField0_ |= 0x00000800; - totalCompactingKVs_ = value; - onChanged(); - return this; - } - public Builder clearTotalCompactingKVs() { - bitField0_ = (bitField0_ & ~0x00000800); - totalCompactingKVs_ = 0L; - onChanged(); - return this; - } - - // optional int64 currentCompactedKVs = 13; - private long currentCompactedKVs_ ; - public boolean hasCurrentCompactedKVs() { - return ((bitField0_ & 0x00001000) == 0x00001000); - } - public long getCurrentCompactedKVs() { - return currentCompactedKVs_; - } - public Builder setCurrentCompactedKVs(long value) { - bitField0_ |= 0x00001000; - currentCompactedKVs_ = value; - onChanged(); - return this; - } - public Builder clearCurrentCompactedKVs() { - bitField0_ = (bitField0_ & ~0x00001000); - currentCompactedKVs_ = 0L; - onChanged(); - return this; - } - // @@protoc_insertion_point(builder_scope:org.apache.hadoop.hbase.rest.protobuf.generated.StorageClusterStatus.Region) } @@ -2811,25 +2412,20 @@ public final class StorageClusterStatusMessage { java.lang.String[] descriptorData = { "\n!StorageClusterStatusMessage.proto\022/org" + ".apache.hadoop.hbase.rest.protobuf.gener" + - "ated\"\333\005\n\024StorageClusterStatus\022]\n\tliveNod" + + "ated\"\222\004\n\024StorageClusterStatus\022]\n\tliveNod" + "es\030\001 \003(\0132J.org.apache.hadoop.hbase.rest." + "protobuf.generated.StorageClusterStatus." + "Node\022\021\n\tdeadNodes\030\002 \003(\t\022\017\n\007regions\030\003 \001(\005" + "\022\020\n\010requests\030\004 \001(\005\022\023\n\013averageLoad\030\005 \001(\001\032" + - "\322\002\n\006Region\022\014\n\004name\030\001 \002(\014\022\016\n\006stores\030\002 \001(\005" + + "\211\001\n\006Region\022\014\n\004name\030\001 \002(\014\022\016\n\006stores\030\002 \001(\005" + "\022\022\n\nstorefiles\030\003 \001(\005\022\027\n\017storefileSizeMB\030" + "\004 \001(\005\022\026\n\016memstoreSizeMB\030\005 \001(\005\022\034\n\024storefi", - "leIndexSizeMB\030\006 \001(\005\022\031\n\021readRequestsCount" + - "\030\007 \001(\003\022\032\n\022writeRequestsCount\030\010 \001(\003\022\027\n\017ro" + - "otIndexSizeKB\030\t \001(\005\022\036\n\026totalStaticIndexS" + - "izeKB\030\n \001(\005\022\036\n\026totalStaticBloomSizeKB\030\013 " + - "\001(\005\022\032\n\022totalCompactingKVs\030\014 \001(\003\022\033\n\023curre" + - "ntCompactedKVs\030\r \001(\003\032\303\001\n\004Node\022\014\n\004name\030\001 " + - "\002(\t\022\021\n\tstartCode\030\002 \001(\003\022\020\n\010requests\030\003 \001(\005" + - "\022\022\n\nheapSizeMB\030\004 \001(\005\022\025\n\rmaxHeapSizeMB\030\005 " + - "\001(\005\022]\n\007regions\030\006 \003(\0132L.org.apache.hadoop" + - ".hbase.rest.protobuf.generated.StorageCl", - "usterStatus.Region" + "leIndexSizeMB\030\006 \001(\005\032\303\001\n\004Node\022\014\n\004name\030\001 \002" + + "(\t\022\021\n\tstartCode\030\002 \001(\003\022\020\n\010requests\030\003 \001(\005\022" + + "\022\n\nheapSizeMB\030\004 \001(\005\022\025\n\rmaxHeapSizeMB\030\005 \001" + + "(\005\022]\n\007regions\030\006 \003(\0132L.org.apache.hadoop." + + "hbase.rest.protobuf.generated.StorageClu" + + "sterStatus.Region" }; com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner = new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() { @@ -2849,7 +2445,7 @@ public final class StorageClusterStatusMessage { internal_static_org_apache_hadoop_hbase_rest_protobuf_generated_StorageClusterStatus_Region_fieldAccessorTable = new com.google.protobuf.GeneratedMessage.FieldAccessorTable( internal_static_org_apache_hadoop_hbase_rest_protobuf_generated_StorageClusterStatus_Region_descriptor, - new java.lang.String[] { "Name", "Stores", "Storefiles", "StorefileSizeMB", "MemstoreSizeMB", "StorefileIndexSizeMB", "ReadRequestsCount", "WriteRequestsCount", "RootIndexSizeKB", "TotalStaticIndexSizeKB", "TotalStaticBloomSizeKB", "TotalCompactingKVs", "CurrentCompactedKVs", }, + new java.lang.String[] { "Name", "Stores", "Storefiles", "StorefileSizeMB", "MemstoreSizeMB", "StorefileIndexSizeMB", }, org.apache.hadoop.hbase.rest.protobuf.generated.StorageClusterStatusMessage.StorageClusterStatus.Region.class, org.apache.hadoop.hbase.rest.protobuf.generated.StorageClusterStatusMessage.StorageClusterStatus.Region.Builder.class); internal_static_org_apache_hadoop_hbase_rest_protobuf_generated_StorageClusterStatus_Node_descriptor = diff --git src/main/java/org/apache/hadoop/hbase/thrift/ThriftServerRunner.java src/main/java/org/apache/hadoop/hbase/thrift/ThriftServerRunner.java index 60eb426..e045a6c 100644 --- src/main/java/org/apache/hadoop/hbase/thrift/ThriftServerRunner.java +++ src/main/java/org/apache/hadoop/hbase/thrift/ThriftServerRunner.java @@ -1130,7 +1130,7 @@ public class ThriftServerRunner implements Runnable { @Override public List scannerGet(int id) throws IllegalArgument, IOError { - return scannerGetList(id,1); + return scannerGetList(id, 1); } public int scannerOpenWithScan(ByteBuffer tableName, TScan tScan, @@ -1331,26 +1331,18 @@ public class ThriftServerRunner implements Runnable { } @Override - public List getRowOrBefore(ByteBuffer tableName, ByteBuffer row, - ByteBuffer family) throws IOError { - try { - HTable table = getTable(getBytes(tableName)); - Result result = table.getRowOrBefore(getBytes(row), getBytes(family)); - return ThriftUtilities.cellFromHBase(result.raw()); - } catch (IOException e) { - LOG.warn(e.getMessage(), e); - throw new IOError(e.getMessage()); - } - } - - @Override public TRegionInfo getRegionInfo(ByteBuffer searchRow) throws IOError { try { HTable table = getTable(HConstants.META_TABLE_NAME); byte[] row = getBytes(searchRow); - Result startRowResult = table.getRowOrBefore( - row, HConstants.CATALOG_FAMILY); + Scan scan = new Scan(); + scan.addColumn(HConstants.CATALOG_FAMILY, HConstants.REGIONINFO_QUALIFIER); + byte[] b = new byte[searchRow.remaining()]; + searchRow.get(b, 0, b.length); + scan.setStartRow(b); + ResultScanner scanner = table.getScanner(scan); + Result startRowResult = scanner.next(); if (startRowResult == null) { throw new IOException("Cannot find row in .META., row=" + Bytes.toStringBinary(row)); diff --git src/main/java/org/apache/hadoop/hbase/thrift/generated/AlreadyExists.java src/main/java/org/apache/hadoop/hbase/thrift/generated/AlreadyExists.java index a5b81f5..abeac63 100644 --- src/main/java/org/apache/hadoop/hbase/thrift/generated/AlreadyExists.java +++ src/main/java/org/apache/hadoop/hbase/thrift/generated/AlreadyExists.java @@ -6,6 +6,7 @@ */ package org.apache.hadoop.hbase.thrift.generated; +import org.apache.commons.lang.builder.HashCodeBuilder; import org.apache.thrift.scheme.IScheme; import org.apache.thrift.scheme.SchemeFactory; import org.apache.thrift.scheme.StandardScheme; @@ -226,7 +227,14 @@ public class AlreadyExists extends Exception implements org.apache.thrift.TBase< @Override public int hashCode() { - return 0; + HashCodeBuilder builder = new HashCodeBuilder(); + + boolean present_message = true && (isSetMessage()); + builder.append(present_message); + if (present_message) + builder.append(message); + + return builder.toHashCode(); } public int compareTo(AlreadyExists other) { diff --git src/main/java/org/apache/hadoop/hbase/thrift/generated/BatchMutation.java src/main/java/org/apache/hadoop/hbase/thrift/generated/BatchMutation.java index d5df940..d535baf 100644 --- src/main/java/org/apache/hadoop/hbase/thrift/generated/BatchMutation.java +++ src/main/java/org/apache/hadoop/hbase/thrift/generated/BatchMutation.java @@ -6,6 +6,7 @@ */ package org.apache.hadoop.hbase.thrift.generated; +import org.apache.commons.lang.builder.HashCodeBuilder; import org.apache.thrift.scheme.IScheme; import org.apache.thrift.scheme.SchemeFactory; import org.apache.thrift.scheme.StandardScheme; @@ -314,7 +315,19 @@ public class BatchMutation implements org.apache.thrift.TBase(_list0.size); for (int _i1 = 0; _i1 < _list0.size; ++_i1) { - Mutation _elem2; // optional + Mutation _elem2; // required _elem2 = new Mutation(); _elem2.read(iprot); struct.mutations.add(_elem2); @@ -534,7 +547,7 @@ public class BatchMutation implements org.apache.thrift.TBase(_list5.size); for (int _i6 = 0; _i6 < _list5.size; ++_i6) { - Mutation _elem7; // optional + Mutation _elem7; // required _elem7 = new Mutation(); _elem7.read(iprot); struct.mutations.add(_elem7); diff --git src/main/java/org/apache/hadoop/hbase/thrift/generated/ColumnDescriptor.java src/main/java/org/apache/hadoop/hbase/thrift/generated/ColumnDescriptor.java index 4ce85e7..047de4a 100644 --- src/main/java/org/apache/hadoop/hbase/thrift/generated/ColumnDescriptor.java +++ src/main/java/org/apache/hadoop/hbase/thrift/generated/ColumnDescriptor.java @@ -6,6 +6,7 @@ */ package org.apache.hadoop.hbase.thrift.generated; +import org.apache.commons.lang.builder.HashCodeBuilder; import org.apache.thrift.scheme.IScheme; import org.apache.thrift.scheme.SchemeFactory; import org.apache.thrift.scheme.StandardScheme; @@ -730,7 +731,54 @@ public class ColumnDescriptor implements org.apache.thrift.TBase mutations, Map attributes) throws IOError, IllegalArgument, org.apache.thrift.TException; @@ -319,7 +320,7 @@ public class Hbase { * * @param timestamp timestamp * - * @param attributes Put attributes + * @param attributes Mutation attributes */ public void mutateRowTs(ByteBuffer tableName, ByteBuffer row, List mutations, long timestamp, Map attributes) throws IOError, IllegalArgument, org.apache.thrift.TException; @@ -333,7 +334,7 @@ public class Hbase { * * @param rowBatches list of row batches * - * @param attributes Put attributes + * @param attributes Mutation attributes */ public void mutateRows(ByteBuffer tableName, List rowBatches, Map attributes) throws IOError, IllegalArgument, org.apache.thrift.TException; @@ -349,7 +350,7 @@ public class Hbase { * * @param timestamp timestamp * - * @param attributes Put attributes + * @param attributes Mutation attributes */ public void mutateRowsTs(ByteBuffer tableName, List rowBatches, long timestamp, Map attributes) throws IOError, IllegalArgument, org.apache.thrift.TException; @@ -582,19 +583,6 @@ public class Hbase { public void scannerClose(int id) throws IOError, IllegalArgument, org.apache.thrift.TException; /** - * Get the row just before the specified one. - * - * @return value for specified row/column - * - * @param tableName name of table - * - * @param row row key - * - * @param family column name - */ - public List getRowOrBefore(ByteBuffer tableName, ByteBuffer row, ByteBuffer family) throws IOError, org.apache.thrift.TException; - - /** * Get the regininfo for the specified row. It scans * the metatable to find region's start and end keys. * @@ -686,8 +674,6 @@ public class Hbase { public void scannerClose(int id, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException; - public void getRowOrBefore(ByteBuffer tableName, ByteBuffer row, ByteBuffer family, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException; - public void getRegionInfo(ByteBuffer row, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException; } @@ -1796,34 +1782,6 @@ public class Hbase { return; } - public List getRowOrBefore(ByteBuffer tableName, ByteBuffer row, ByteBuffer family) throws IOError, org.apache.thrift.TException - { - send_getRowOrBefore(tableName, row, family); - return recv_getRowOrBefore(); - } - - public void send_getRowOrBefore(ByteBuffer tableName, ByteBuffer row, ByteBuffer family) throws org.apache.thrift.TException - { - getRowOrBefore_args args = new getRowOrBefore_args(); - args.setTableName(tableName); - args.setRow(row); - args.setFamily(family); - sendBase("getRowOrBefore", args); - } - - public List recv_getRowOrBefore() throws IOError, org.apache.thrift.TException - { - getRowOrBefore_result result = new getRowOrBefore_result(); - receiveBase(result, "getRowOrBefore"); - if (result.isSetSuccess()) { - return result.success; - } - if (result.io != null) { - throw result.io; - } - throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "getRowOrBefore failed: unknown result"); - } - public TRegionInfo getRegionInfo(ByteBuffer row) throws IOError, org.apache.thrift.TException { send_getRegionInfo(row); @@ -3371,44 +3329,6 @@ public class Hbase { } } - public void getRowOrBefore(ByteBuffer tableName, ByteBuffer row, ByteBuffer family, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException { - checkReady(); - getRowOrBefore_call method_call = new getRowOrBefore_call(tableName, row, family, resultHandler, this, ___protocolFactory, ___transport); - this.___currentMethod = method_call; - ___manager.call(method_call); - } - - public static class getRowOrBefore_call extends org.apache.thrift.async.TAsyncMethodCall { - private ByteBuffer tableName; - private ByteBuffer row; - private ByteBuffer family; - public getRowOrBefore_call(ByteBuffer tableName, ByteBuffer row, ByteBuffer family, org.apache.thrift.async.AsyncMethodCallback resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException { - super(client, protocolFactory, transport, resultHandler, false); - this.tableName = tableName; - this.row = row; - this.family = family; - } - - public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException { - prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("getRowOrBefore", org.apache.thrift.protocol.TMessageType.CALL, 0)); - getRowOrBefore_args args = new getRowOrBefore_args(); - args.setTableName(tableName); - args.setRow(row); - args.setFamily(family); - args.write(prot); - prot.writeMessageEnd(); - } - - public List getResult() throws IOError, org.apache.thrift.TException { - if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) { - throw new IllegalStateException("Method call not finished!"); - } - org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array()); - org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport); - return (new Client(prot)).recv_getRowOrBefore(); - } - } - public void getRegionInfo(ByteBuffer row, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException { checkReady(); getRegionInfo_call method_call = new getRegionInfo_call(row, resultHandler, this, ___protocolFactory, ___transport); @@ -3493,7 +3413,6 @@ public class Hbase { processMap.put("scannerGet", new scannerGet()); processMap.put("scannerGetList", new scannerGetList()); processMap.put("scannerClose", new scannerClose()); - processMap.put("getRowOrBefore", new getRowOrBefore()); processMap.put("getRegionInfo", new getRegionInfo()); return processMap; } @@ -4306,26 +4225,6 @@ public class Hbase { } } - private static class getRowOrBefore extends org.apache.thrift.ProcessFunction { - public getRowOrBefore() { - super("getRowOrBefore"); - } - - protected getRowOrBefore_args getEmptyArgsInstance() { - return new getRowOrBefore_args(); - } - - protected getRowOrBefore_result getResult(I iface, getRowOrBefore_args args) throws org.apache.thrift.TException { - getRowOrBefore_result result = new getRowOrBefore_result(); - try { - result.success = iface.getRowOrBefore(args.tableName, args.row, args.family); - } catch (IOError io) { - result.io = io; - } - return result; - } - } - private static class getRegionInfo extends org.apache.thrift.ProcessFunction { public getRegionInfo() { super("getRegionInfo"); @@ -4565,7 +4464,14 @@ public class Hbase { @Override public int hashCode() { - return 0; + HashCodeBuilder builder = new HashCodeBuilder(); + + boolean present_tableName = true && (isSetTableName()); + builder.append(present_tableName); + if (present_tableName) + builder.append(tableName); + + return builder.toHashCode(); } public int compareTo(enableTable_args other) { @@ -4918,7 +4824,14 @@ public class Hbase { @Override public int hashCode() { - return 0; + HashCodeBuilder builder = new HashCodeBuilder(); + + boolean present_io = true && (isSetIo()); + builder.append(present_io); + if (present_io) + builder.append(io); + + return builder.toHashCode(); } public int compareTo(enableTable_result other) { @@ -5295,7 +5208,14 @@ public class Hbase { @Override public int hashCode() { - return 0; + HashCodeBuilder builder = new HashCodeBuilder(); + + boolean present_tableName = true && (isSetTableName()); + builder.append(present_tableName); + if (present_tableName) + builder.append(tableName); + + return builder.toHashCode(); } public int compareTo(disableTable_args other) { @@ -5648,7 +5568,14 @@ public class Hbase { @Override public int hashCode() { - return 0; + HashCodeBuilder builder = new HashCodeBuilder(); + + boolean present_io = true && (isSetIo()); + builder.append(present_io); + if (present_io) + builder.append(io); + + return builder.toHashCode(); } public int compareTo(disableTable_result other) { @@ -6025,7 +5952,14 @@ public class Hbase { @Override public int hashCode() { - return 0; + HashCodeBuilder builder = new HashCodeBuilder(); + + boolean present_tableName = true && (isSetTableName()); + builder.append(present_tableName); + if (present_tableName) + builder.append(tableName); + + return builder.toHashCode(); } public int compareTo(isTableEnabled_args other) { @@ -6440,7 +6374,19 @@ public class Hbase { @Override public int hashCode() { - return 0; + HashCodeBuilder builder = new HashCodeBuilder(); + + boolean present_success = true; + builder.append(present_success); + if (present_success) + builder.append(success); + + boolean present_io = true && (isSetIo()); + builder.append(present_io); + if (present_io) + builder.append(io); + + return builder.toHashCode(); } public int compareTo(isTableEnabled_result other) { @@ -6520,6 +6466,8 @@ public class Hbase { private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException { try { + // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor. + __isset_bit_vector = new BitSet(1); read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in))); } catch (org.apache.thrift.TException te) { throw new java.io.IOException(te); @@ -6840,7 +6788,14 @@ public class Hbase { @Override public int hashCode() { - return 0; + HashCodeBuilder builder = new HashCodeBuilder(); + + boolean present_tableNameOrRegionName = true && (isSetTableNameOrRegionName()); + builder.append(present_tableNameOrRegionName); + if (present_tableNameOrRegionName) + builder.append(tableNameOrRegionName); + + return builder.toHashCode(); } public int compareTo(compact_args other) { @@ -7193,7 +7148,14 @@ public class Hbase { @Override public int hashCode() { - return 0; + HashCodeBuilder builder = new HashCodeBuilder(); + + boolean present_io = true && (isSetIo()); + builder.append(present_io); + if (present_io) + builder.append(io); + + return builder.toHashCode(); } public int compareTo(compact_result other) { @@ -7558,7 +7520,14 @@ public class Hbase { @Override public int hashCode() { - return 0; + HashCodeBuilder builder = new HashCodeBuilder(); + + boolean present_tableNameOrRegionName = true && (isSetTableNameOrRegionName()); + builder.append(present_tableNameOrRegionName); + if (present_tableNameOrRegionName) + builder.append(tableNameOrRegionName); + + return builder.toHashCode(); } public int compareTo(majorCompact_args other) { @@ -7911,7 +7880,14 @@ public class Hbase { @Override public int hashCode() { - return 0; + HashCodeBuilder builder = new HashCodeBuilder(); + + boolean present_io = true && (isSetIo()); + builder.append(present_io); + if (present_io) + builder.append(io); + + return builder.toHashCode(); } public int compareTo(majorCompact_result other) { @@ -8201,7 +8177,9 @@ public class Hbase { @Override public int hashCode() { - return 0; + HashCodeBuilder builder = new HashCodeBuilder(); + + return builder.toHashCode(); } public int compareTo(getTableNames_args other) { @@ -8590,7 +8568,19 @@ public class Hbase { @Override public int hashCode() { - return 0; + HashCodeBuilder builder = new HashCodeBuilder(); + + boolean present_success = true && (isSetSuccess()); + builder.append(present_success); + if (present_success) + builder.append(success); + + boolean present_io = true && (isSetIo()); + builder.append(present_io); + if (present_io) + builder.append(io); + + return builder.toHashCode(); } public int compareTo(getTableNames_result other) { @@ -8705,7 +8695,7 @@ public class Hbase { struct.success = new ArrayList(_list26.size); for (int _i27 = 0; _i27 < _list26.size; ++_i27) { - ByteBuffer _elem28; // optional + ByteBuffer _elem28; // required _elem28 = iprot.readBinary(); struct.success.add(_elem28); } @@ -8806,7 +8796,7 @@ public class Hbase { struct.success = new ArrayList(_list31.size); for (int _i32 = 0; _i32 < _list31.size; ++_i32) { - ByteBuffer _elem33; // optional + ByteBuffer _elem33; // required _elem33 = iprot.readBinary(); struct.success.add(_elem33); } @@ -9040,7 +9030,14 @@ public class Hbase { @Override public int hashCode() { - return 0; + HashCodeBuilder builder = new HashCodeBuilder(); + + boolean present_tableName = true && (isSetTableName()); + builder.append(present_tableName); + if (present_tableName) + builder.append(tableName); + + return builder.toHashCode(); } public int compareTo(getColumnDescriptors_args other) { @@ -9477,7 +9474,19 @@ public class Hbase { @Override public int hashCode() { - return 0; + HashCodeBuilder builder = new HashCodeBuilder(); + + boolean present_success = true && (isSetSuccess()); + builder.append(present_success); + if (present_success) + builder.append(success); + + boolean present_io = true && (isSetIo()); + builder.append(present_io); + if (present_io) + builder.append(io); + + return builder.toHashCode(); } public int compareTo(getColumnDescriptors_result other) { @@ -9593,7 +9602,7 @@ public class Hbase { for (int _i35 = 0; _i35 < _map34.size; ++_i35) { ByteBuffer _key36; // required - ColumnDescriptor _val37; // required + ColumnDescriptor _val37; // optional _key36 = iprot.readBinary(); _val37 = new ColumnDescriptor(); _val37.read(iprot); @@ -9699,7 +9708,7 @@ public class Hbase { for (int _i41 = 0; _i41 < _map40.size; ++_i41) { ByteBuffer _key42; // required - ColumnDescriptor _val43; // required + ColumnDescriptor _val43; // optional _key42 = iprot.readBinary(); _val43 = new ColumnDescriptor(); _val43.read(iprot); @@ -9935,7 +9944,14 @@ public class Hbase { @Override public int hashCode() { - return 0; + HashCodeBuilder builder = new HashCodeBuilder(); + + boolean present_tableName = true && (isSetTableName()); + builder.append(present_tableName); + if (present_tableName) + builder.append(tableName); + + return builder.toHashCode(); } public int compareTo(getTableRegions_args other) { @@ -10367,7 +10383,19 @@ public class Hbase { @Override public int hashCode() { - return 0; + HashCodeBuilder builder = new HashCodeBuilder(); + + boolean present_success = true && (isSetSuccess()); + builder.append(present_success); + if (present_success) + builder.append(success); + + boolean present_io = true && (isSetIo()); + builder.append(present_io); + if (present_io) + builder.append(io); + + return builder.toHashCode(); } public int compareTo(getTableRegions_result other) { @@ -10482,7 +10510,7 @@ public class Hbase { struct.success = new ArrayList(_list44.size); for (int _i45 = 0; _i45 < _list44.size; ++_i45) { - TRegionInfo _elem46; // optional + TRegionInfo _elem46; // required _elem46 = new TRegionInfo(); _elem46.read(iprot); struct.success.add(_elem46); @@ -10584,7 +10612,7 @@ public class Hbase { struct.success = new ArrayList(_list49.size); for (int _i50 = 0; _i50 < _list49.size; ++_i50) { - TRegionInfo _elem51; // optional + TRegionInfo _elem51; // required _elem51 = new TRegionInfo(); _elem51.read(iprot); struct.success.add(_elem51); @@ -10910,7 +10938,19 @@ public class Hbase { @Override public int hashCode() { - return 0; + HashCodeBuilder builder = new HashCodeBuilder(); + + boolean present_tableName = true && (isSetTableName()); + builder.append(present_tableName); + if (present_tableName) + builder.append(tableName); + + boolean present_columnFamilies = true && (isSetColumnFamilies()); + builder.append(present_columnFamilies); + if (present_columnFamilies) + builder.append(columnFamilies); + + return builder.toHashCode(); } public int compareTo(createTable_args other) { @@ -11033,7 +11073,7 @@ public class Hbase { struct.columnFamilies = new ArrayList(_list52.size); for (int _i53 = 0; _i53 < _list52.size; ++_i53) { - ColumnDescriptor _elem54; // optional + ColumnDescriptor _elem54; // required _elem54 = new ColumnDescriptor(); _elem54.read(iprot); struct.columnFamilies.add(_elem54); @@ -11130,7 +11170,7 @@ public class Hbase { struct.columnFamilies = new ArrayList(_list57.size); for (int _i58 = 0; _i58 < _list57.size; ++_i58) { - ColumnDescriptor _elem59; // optional + ColumnDescriptor _elem59; // required _elem59 = new ColumnDescriptor(); _elem59.read(iprot); struct.columnFamilies.add(_elem59); @@ -11456,7 +11496,24 @@ public class Hbase { @Override public int hashCode() { - return 0; + HashCodeBuilder builder = new HashCodeBuilder(); + + boolean present_io = true && (isSetIo()); + builder.append(present_io); + if (present_io) + builder.append(io); + + boolean present_ia = true && (isSetIa()); + builder.append(present_ia); + if (present_ia) + builder.append(ia); + + boolean present_exist = true && (isSetExist()); + builder.append(present_exist); + if (present_exist) + builder.append(exist); + + return builder.toHashCode(); } public int compareTo(createTable_result other) { @@ -11919,7 +11976,14 @@ public class Hbase { @Override public int hashCode() { - return 0; + HashCodeBuilder builder = new HashCodeBuilder(); + + boolean present_tableName = true && (isSetTableName()); + builder.append(present_tableName); + if (present_tableName) + builder.append(tableName); + + return builder.toHashCode(); } public int compareTo(deleteTable_args other) { @@ -12272,7 +12336,14 @@ public class Hbase { @Override public int hashCode() { - return 0; + HashCodeBuilder builder = new HashCodeBuilder(); + + boolean present_io = true && (isSetIo()); + builder.append(present_io); + if (present_io) + builder.append(io); + + return builder.toHashCode(); } public int compareTo(deleteTable_result other) { @@ -12907,7 +12978,29 @@ public class Hbase { @Override public int hashCode() { - return 0; + HashCodeBuilder builder = new HashCodeBuilder(); + + boolean present_tableName = true && (isSetTableName()); + builder.append(present_tableName); + if (present_tableName) + builder.append(tableName); + + boolean present_row = true && (isSetRow()); + builder.append(present_row); + if (present_row) + builder.append(row); + + boolean present_column = true && (isSetColumn()); + builder.append(present_column); + if (present_column) + builder.append(column); + + boolean present_attributes = true && (isSetAttributes()); + builder.append(present_attributes); + if (present_attributes) + builder.append(attributes); + + return builder.toHashCode(); } public int compareTo(get_args other) { @@ -13083,7 +13176,7 @@ public class Hbase { for (int _i61 = 0; _i61 < _map60.size; ++_i61) { ByteBuffer _key62; // required - ByteBuffer _val63; // required + ByteBuffer _val63; // optional _key62 = iprot.readBinary(); _val63 = iprot.readBinary(); struct.attributes.put(_key62, _val63); @@ -13213,7 +13306,7 @@ public class Hbase { for (int _i67 = 0; _i67 < _map66.size; ++_i67) { ByteBuffer _key68; // required - ByteBuffer _val69; // required + ByteBuffer _val69; // optional _key68 = iprot.readBinary(); _val69 = iprot.readBinary(); struct.attributes.put(_key68, _val69); @@ -13500,7 +13593,19 @@ public class Hbase { @Override public int hashCode() { - return 0; + HashCodeBuilder builder = new HashCodeBuilder(); + + boolean present_success = true && (isSetSuccess()); + builder.append(present_success); + if (present_success) + builder.append(success); + + boolean present_io = true && (isSetIo()); + builder.append(present_io); + if (present_io) + builder.append(io); + + return builder.toHashCode(); } public int compareTo(get_result other) { @@ -13615,7 +13720,7 @@ public class Hbase { struct.success = new ArrayList(_list70.size); for (int _i71 = 0; _i71 < _list70.size; ++_i71) { - TCell _elem72; // optional + TCell _elem72; // required _elem72 = new TCell(); _elem72.read(iprot); struct.success.add(_elem72); @@ -13717,7 +13822,7 @@ public class Hbase { struct.success = new ArrayList(_list75.size); for (int _i76 = 0; _i76 < _list75.size; ++_i76) { - TCell _elem77; // optional + TCell _elem77; // required _elem77 = new TCell(); _elem77.read(iprot); struct.success.add(_elem77); @@ -14284,7 +14389,34 @@ public class Hbase { @Override public int hashCode() { - return 0; + HashCodeBuilder builder = new HashCodeBuilder(); + + boolean present_tableName = true && (isSetTableName()); + builder.append(present_tableName); + if (present_tableName) + builder.append(tableName); + + boolean present_row = true && (isSetRow()); + builder.append(present_row); + if (present_row) + builder.append(row); + + boolean present_column = true && (isSetColumn()); + builder.append(present_column); + if (present_column) + builder.append(column); + + boolean present_numVersions = true; + builder.append(present_numVersions); + if (present_numVersions) + builder.append(numVersions); + + boolean present_attributes = true && (isSetAttributes()); + builder.append(present_attributes); + if (present_attributes) + builder.append(attributes); + + return builder.toHashCode(); } public int compareTo(getVer_args other) { @@ -14484,7 +14616,7 @@ public class Hbase { for (int _i79 = 0; _i79 < _map78.size; ++_i79) { ByteBuffer _key80; // required - ByteBuffer _val81; // required + ByteBuffer _val81; // optional _key80 = iprot.readBinary(); _val81 = iprot.readBinary(); struct.attributes.put(_key80, _val81); @@ -14627,7 +14759,7 @@ public class Hbase { for (int _i85 = 0; _i85 < _map84.size; ++_i85) { ByteBuffer _key86; // required - ByteBuffer _val87; // required + ByteBuffer _val87; // optional _key86 = iprot.readBinary(); _val87 = iprot.readBinary(); struct.attributes.put(_key86, _val87); @@ -14914,7 +15046,19 @@ public class Hbase { @Override public int hashCode() { - return 0; + HashCodeBuilder builder = new HashCodeBuilder(); + + boolean present_success = true && (isSetSuccess()); + builder.append(present_success); + if (present_success) + builder.append(success); + + boolean present_io = true && (isSetIo()); + builder.append(present_io); + if (present_io) + builder.append(io); + + return builder.toHashCode(); } public int compareTo(getVer_result other) { @@ -15029,7 +15173,7 @@ public class Hbase { struct.success = new ArrayList(_list88.size); for (int _i89 = 0; _i89 < _list88.size; ++_i89) { - TCell _elem90; // optional + TCell _elem90; // required _elem90 = new TCell(); _elem90.read(iprot); struct.success.add(_elem90); @@ -15131,7 +15275,7 @@ public class Hbase { struct.success = new ArrayList(_list93.size); for (int _i94 = 0; _i94 < _list93.size; ++_i94) { - TCell _elem95; // optional + TCell _elem95; // required _elem95 = new TCell(); _elem95.read(iprot); struct.success.add(_elem95); @@ -15769,7 +15913,39 @@ public class Hbase { @Override public int hashCode() { - return 0; + HashCodeBuilder builder = new HashCodeBuilder(); + + boolean present_tableName = true && (isSetTableName()); + builder.append(present_tableName); + if (present_tableName) + builder.append(tableName); + + boolean present_row = true && (isSetRow()); + builder.append(present_row); + if (present_row) + builder.append(row); + + boolean present_column = true && (isSetColumn()); + builder.append(present_column); + if (present_column) + builder.append(column); + + boolean present_timestamp = true; + builder.append(present_timestamp); + if (present_timestamp) + builder.append(timestamp); + + boolean present_numVersions = true; + builder.append(present_numVersions); + if (present_numVersions) + builder.append(numVersions); + + boolean present_attributes = true && (isSetAttributes()); + builder.append(present_attributes); + if (present_attributes) + builder.append(attributes); + + return builder.toHashCode(); } public int compareTo(getVerTs_args other) { @@ -15989,7 +16165,7 @@ public class Hbase { for (int _i97 = 0; _i97 < _map96.size; ++_i97) { ByteBuffer _key98; // required - ByteBuffer _val99; // required + ByteBuffer _val99; // optional _key98 = iprot.readBinary(); _val99 = iprot.readBinary(); struct.attributes.put(_key98, _val99); @@ -16145,7 +16321,7 @@ public class Hbase { for (int _i103 = 0; _i103 < _map102.size; ++_i103) { ByteBuffer _key104; // required - ByteBuffer _val105; // required + ByteBuffer _val105; // optional _key104 = iprot.readBinary(); _val105 = iprot.readBinary(); struct.attributes.put(_key104, _val105); @@ -16432,7 +16608,19 @@ public class Hbase { @Override public int hashCode() { - return 0; + HashCodeBuilder builder = new HashCodeBuilder(); + + boolean present_success = true && (isSetSuccess()); + builder.append(present_success); + if (present_success) + builder.append(success); + + boolean present_io = true && (isSetIo()); + builder.append(present_io); + if (present_io) + builder.append(io); + + return builder.toHashCode(); } public int compareTo(getVerTs_result other) { @@ -16547,7 +16735,7 @@ public class Hbase { struct.success = new ArrayList(_list106.size); for (int _i107 = 0; _i107 < _list106.size; ++_i107) { - TCell _elem108; // optional + TCell _elem108; // required _elem108 = new TCell(); _elem108.read(iprot); struct.success.add(_elem108); @@ -16649,7 +16837,7 @@ public class Hbase { struct.success = new ArrayList(_list111.size); for (int _i112 = 0; _i112 < _list111.size; ++_i112) { - TCell _elem113; // optional + TCell _elem113; // required _elem113 = new TCell(); _elem113.read(iprot); struct.success.add(_elem113); @@ -17061,7 +17249,24 @@ public class Hbase { @Override public int hashCode() { - return 0; + HashCodeBuilder builder = new HashCodeBuilder(); + + boolean present_tableName = true && (isSetTableName()); + builder.append(present_tableName); + if (present_tableName) + builder.append(tableName); + + boolean present_row = true && (isSetRow()); + builder.append(present_row); + if (present_row) + builder.append(row); + + boolean present_attributes = true && (isSetAttributes()); + builder.append(present_attributes); + if (present_attributes) + builder.append(attributes); + + return builder.toHashCode(); } public int compareTo(getRow_args other) { @@ -17211,7 +17416,7 @@ public class Hbase { for (int _i115 = 0; _i115 < _map114.size; ++_i115) { ByteBuffer _key116; // required - ByteBuffer _val117; // required + ByteBuffer _val117; // optional _key116 = iprot.readBinary(); _val117 = iprot.readBinary(); struct.attributes.put(_key116, _val117); @@ -17326,7 +17531,7 @@ public class Hbase { for (int _i121 = 0; _i121 < _map120.size; ++_i121) { ByteBuffer _key122; // required - ByteBuffer _val123; // required + ByteBuffer _val123; // optional _key122 = iprot.readBinary(); _val123 = iprot.readBinary(); struct.attributes.put(_key122, _val123); @@ -17613,7 +17818,19 @@ public class Hbase { @Override public int hashCode() { - return 0; + HashCodeBuilder builder = new HashCodeBuilder(); + + boolean present_success = true && (isSetSuccess()); + builder.append(present_success); + if (present_success) + builder.append(success); + + boolean present_io = true && (isSetIo()); + builder.append(present_io); + if (present_io) + builder.append(io); + + return builder.toHashCode(); } public int compareTo(getRow_result other) { @@ -17728,7 +17945,7 @@ public class Hbase { struct.success = new ArrayList(_list124.size); for (int _i125 = 0; _i125 < _list124.size; ++_i125) { - TRowResult _elem126; // optional + TRowResult _elem126; // required _elem126 = new TRowResult(); _elem126.read(iprot); struct.success.add(_elem126); @@ -17830,7 +18047,7 @@ public class Hbase { struct.success = new ArrayList(_list129.size); for (int _i130 = 0; _i130 < _list129.size; ++_i130) { - TRowResult _elem131; // optional + TRowResult _elem131; // required _elem131 = new TRowResult(); _elem131.read(iprot); struct.success.add(_elem131); @@ -18333,7 +18550,29 @@ public class Hbase { @Override public int hashCode() { - return 0; + HashCodeBuilder builder = new HashCodeBuilder(); + + boolean present_tableName = true && (isSetTableName()); + builder.append(present_tableName); + if (present_tableName) + builder.append(tableName); + + boolean present_row = true && (isSetRow()); + builder.append(present_row); + if (present_row) + builder.append(row); + + boolean present_columns = true && (isSetColumns()); + builder.append(present_columns); + if (present_columns) + builder.append(columns); + + boolean present_attributes = true && (isSetAttributes()); + builder.append(present_attributes); + if (present_attributes) + builder.append(attributes); + + return builder.toHashCode(); } public int compareTo(getRowWithColumns_args other) { @@ -18500,7 +18739,7 @@ public class Hbase { struct.columns = new ArrayList(_list132.size); for (int _i133 = 0; _i133 < _list132.size; ++_i133) { - ByteBuffer _elem134; // optional + ByteBuffer _elem134; // required _elem134 = iprot.readBinary(); struct.columns.add(_elem134); } @@ -18519,7 +18758,7 @@ public class Hbase { for (int _i136 = 0; _i136 < _map135.size; ++_i136) { ByteBuffer _key137; // required - ByteBuffer _val138; // required + ByteBuffer _val138; // optional _key137 = iprot.readBinary(); _val138 = iprot.readBinary(); struct.attributes.put(_key137, _val138); @@ -18657,7 +18896,7 @@ public class Hbase { struct.columns = new ArrayList(_list143.size); for (int _i144 = 0; _i144 < _list143.size; ++_i144) { - ByteBuffer _elem145; // optional + ByteBuffer _elem145; // required _elem145 = iprot.readBinary(); struct.columns.add(_elem145); } @@ -18671,7 +18910,7 @@ public class Hbase { for (int _i147 = 0; _i147 < _map146.size; ++_i147) { ByteBuffer _key148; // required - ByteBuffer _val149; // required + ByteBuffer _val149; // optional _key148 = iprot.readBinary(); _val149 = iprot.readBinary(); struct.attributes.put(_key148, _val149); @@ -18958,7 +19197,19 @@ public class Hbase { @Override public int hashCode() { - return 0; + HashCodeBuilder builder = new HashCodeBuilder(); + + boolean present_success = true && (isSetSuccess()); + builder.append(present_success); + if (present_success) + builder.append(success); + + boolean present_io = true && (isSetIo()); + builder.append(present_io); + if (present_io) + builder.append(io); + + return builder.toHashCode(); } public int compareTo(getRowWithColumns_result other) { @@ -19073,7 +19324,7 @@ public class Hbase { struct.success = new ArrayList(_list150.size); for (int _i151 = 0; _i151 < _list150.size; ++_i151) { - TRowResult _elem152; // optional + TRowResult _elem152; // required _elem152 = new TRowResult(); _elem152.read(iprot); struct.success.add(_elem152); @@ -19175,7 +19426,7 @@ public class Hbase { struct.success = new ArrayList(_list155.size); for (int _i156 = 0; _i156 < _list155.size; ++_i156) { - TRowResult _elem157; // optional + TRowResult _elem157; // required _elem157 = new TRowResult(); _elem157.read(iprot); struct.success.add(_elem157); @@ -19661,7 +19912,29 @@ public class Hbase { @Override public int hashCode() { - return 0; + HashCodeBuilder builder = new HashCodeBuilder(); + + boolean present_tableName = true && (isSetTableName()); + builder.append(present_tableName); + if (present_tableName) + builder.append(tableName); + + boolean present_row = true && (isSetRow()); + builder.append(present_row); + if (present_row) + builder.append(row); + + boolean present_timestamp = true; + builder.append(present_timestamp); + if (present_timestamp) + builder.append(timestamp); + + boolean present_attributes = true && (isSetAttributes()); + builder.append(present_attributes); + if (present_attributes) + builder.append(attributes); + + return builder.toHashCode(); } public int compareTo(getRowTs_args other) { @@ -19835,7 +20108,7 @@ public class Hbase { for (int _i159 = 0; _i159 < _map158.size; ++_i159) { ByteBuffer _key160; // required - ByteBuffer _val161; // required + ByteBuffer _val161; // optional _key160 = iprot.readBinary(); _val161 = iprot.readBinary(); struct.attributes.put(_key160, _val161); @@ -19963,7 +20236,7 @@ public class Hbase { for (int _i165 = 0; _i165 < _map164.size; ++_i165) { ByteBuffer _key166; // required - ByteBuffer _val167; // required + ByteBuffer _val167; // optional _key166 = iprot.readBinary(); _val167 = iprot.readBinary(); struct.attributes.put(_key166, _val167); @@ -20250,7 +20523,19 @@ public class Hbase { @Override public int hashCode() { - return 0; + HashCodeBuilder builder = new HashCodeBuilder(); + + boolean present_success = true && (isSetSuccess()); + builder.append(present_success); + if (present_success) + builder.append(success); + + boolean present_io = true && (isSetIo()); + builder.append(present_io); + if (present_io) + builder.append(io); + + return builder.toHashCode(); } public int compareTo(getRowTs_result other) { @@ -20365,7 +20650,7 @@ public class Hbase { struct.success = new ArrayList(_list168.size); for (int _i169 = 0; _i169 < _list168.size; ++_i169) { - TRowResult _elem170; // optional + TRowResult _elem170; // required _elem170 = new TRowResult(); _elem170.read(iprot); struct.success.add(_elem170); @@ -20467,7 +20752,7 @@ public class Hbase { struct.success = new ArrayList(_list173.size); for (int _i174 = 0; _i174 < _list173.size; ++_i174) { - TRowResult _elem175; // optional + TRowResult _elem175; // required _elem175 = new TRowResult(); _elem175.read(iprot); struct.success.add(_elem175); @@ -21032,7 +21317,34 @@ public class Hbase { @Override public int hashCode() { - return 0; + HashCodeBuilder builder = new HashCodeBuilder(); + + boolean present_tableName = true && (isSetTableName()); + builder.append(present_tableName); + if (present_tableName) + builder.append(tableName); + + boolean present_row = true && (isSetRow()); + builder.append(present_row); + if (present_row) + builder.append(row); + + boolean present_columns = true && (isSetColumns()); + builder.append(present_columns); + if (present_columns) + builder.append(columns); + + boolean present_timestamp = true; + builder.append(present_timestamp); + if (present_timestamp) + builder.append(timestamp); + + boolean present_attributes = true && (isSetAttributes()); + builder.append(present_attributes); + if (present_attributes) + builder.append(attributes); + + return builder.toHashCode(); } public int compareTo(getRowWithColumnsTs_args other) { @@ -21215,7 +21527,7 @@ public class Hbase { struct.columns = new ArrayList(_list176.size); for (int _i177 = 0; _i177 < _list176.size; ++_i177) { - ByteBuffer _elem178; // optional + ByteBuffer _elem178; // required _elem178 = iprot.readBinary(); struct.columns.add(_elem178); } @@ -21242,7 +21554,7 @@ public class Hbase { for (int _i180 = 0; _i180 < _map179.size; ++_i180) { ByteBuffer _key181; // required - ByteBuffer _val182; // required + ByteBuffer _val182; // optional _key181 = iprot.readBinary(); _val182 = iprot.readBinary(); struct.attributes.put(_key181, _val182); @@ -21389,7 +21701,7 @@ public class Hbase { struct.columns = new ArrayList(_list187.size); for (int _i188 = 0; _i188 < _list187.size; ++_i188) { - ByteBuffer _elem189; // optional + ByteBuffer _elem189; // required _elem189 = iprot.readBinary(); struct.columns.add(_elem189); } @@ -21407,7 +21719,7 @@ public class Hbase { for (int _i191 = 0; _i191 < _map190.size; ++_i191) { ByteBuffer _key192; // required - ByteBuffer _val193; // required + ByteBuffer _val193; // optional _key192 = iprot.readBinary(); _val193 = iprot.readBinary(); struct.attributes.put(_key192, _val193); @@ -21694,7 +22006,19 @@ public class Hbase { @Override public int hashCode() { - return 0; + HashCodeBuilder builder = new HashCodeBuilder(); + + boolean present_success = true && (isSetSuccess()); + builder.append(present_success); + if (present_success) + builder.append(success); + + boolean present_io = true && (isSetIo()); + builder.append(present_io); + if (present_io) + builder.append(io); + + return builder.toHashCode(); } public int compareTo(getRowWithColumnsTs_result other) { @@ -21809,7 +22133,7 @@ public class Hbase { struct.success = new ArrayList(_list194.size); for (int _i195 = 0; _i195 < _list194.size; ++_i195) { - TRowResult _elem196; // optional + TRowResult _elem196; // required _elem196 = new TRowResult(); _elem196.read(iprot); struct.success.add(_elem196); @@ -21911,7 +22235,7 @@ public class Hbase { struct.success = new ArrayList(_list199.size); for (int _i200 = 0; _i200 < _list199.size; ++_i200) { - TRowResult _elem201; // optional + TRowResult _elem201; // required _elem201 = new TRowResult(); _elem201.read(iprot); struct.success.add(_elem201); @@ -22333,7 +22657,24 @@ public class Hbase { @Override public int hashCode() { - return 0; + HashCodeBuilder builder = new HashCodeBuilder(); + + boolean present_tableName = true && (isSetTableName()); + builder.append(present_tableName); + if (present_tableName) + builder.append(tableName); + + boolean present_rows = true && (isSetRows()); + builder.append(present_rows); + if (present_rows) + builder.append(rows); + + boolean present_attributes = true && (isSetAttributes()); + builder.append(present_attributes); + if (present_attributes) + builder.append(attributes); + + return builder.toHashCode(); } public int compareTo(getRows_args other) { @@ -22474,7 +22815,7 @@ public class Hbase { struct.rows = new ArrayList(_list202.size); for (int _i203 = 0; _i203 < _list202.size; ++_i203) { - ByteBuffer _elem204; // optional + ByteBuffer _elem204; // required _elem204 = iprot.readBinary(); struct.rows.add(_elem204); } @@ -22493,7 +22834,7 @@ public class Hbase { for (int _i206 = 0; _i206 < _map205.size; ++_i206) { ByteBuffer _key207; // required - ByteBuffer _val208; // required + ByteBuffer _val208; // optional _key207 = iprot.readBinary(); _val208 = iprot.readBinary(); struct.attributes.put(_key207, _val208); @@ -22616,7 +22957,7 @@ public class Hbase { struct.rows = new ArrayList(_list213.size); for (int _i214 = 0; _i214 < _list213.size; ++_i214) { - ByteBuffer _elem215; // optional + ByteBuffer _elem215; // required _elem215 = iprot.readBinary(); struct.rows.add(_elem215); } @@ -22630,7 +22971,7 @@ public class Hbase { for (int _i217 = 0; _i217 < _map216.size; ++_i217) { ByteBuffer _key218; // required - ByteBuffer _val219; // required + ByteBuffer _val219; // optional _key218 = iprot.readBinary(); _val219 = iprot.readBinary(); struct.attributes.put(_key218, _val219); @@ -22917,7 +23258,19 @@ public class Hbase { @Override public int hashCode() { - return 0; + HashCodeBuilder builder = new HashCodeBuilder(); + + boolean present_success = true && (isSetSuccess()); + builder.append(present_success); + if (present_success) + builder.append(success); + + boolean present_io = true && (isSetIo()); + builder.append(present_io); + if (present_io) + builder.append(io); + + return builder.toHashCode(); } public int compareTo(getRows_result other) { @@ -23032,7 +23385,7 @@ public class Hbase { struct.success = new ArrayList(_list220.size); for (int _i221 = 0; _i221 < _list220.size; ++_i221) { - TRowResult _elem222; // optional + TRowResult _elem222; // required _elem222 = new TRowResult(); _elem222.read(iprot); struct.success.add(_elem222); @@ -23134,7 +23487,7 @@ public class Hbase { struct.success = new ArrayList(_list225.size); for (int _i226 = 0; _i226 < _list225.size; ++_i226) { - TRowResult _elem227; // optional + TRowResult _elem227; // required _elem227 = new TRowResult(); _elem227.read(iprot); struct.success.add(_elem227); @@ -23647,7 +24000,29 @@ public class Hbase { @Override public int hashCode() { - return 0; + HashCodeBuilder builder = new HashCodeBuilder(); + + boolean present_tableName = true && (isSetTableName()); + builder.append(present_tableName); + if (present_tableName) + builder.append(tableName); + + boolean present_rows = true && (isSetRows()); + builder.append(present_rows); + if (present_rows) + builder.append(rows); + + boolean present_columns = true && (isSetColumns()); + builder.append(present_columns); + if (present_columns) + builder.append(columns); + + boolean present_attributes = true && (isSetAttributes()); + builder.append(present_attributes); + if (present_attributes) + builder.append(attributes); + + return builder.toHashCode(); } public int compareTo(getRowsWithColumns_args other) { @@ -23806,7 +24181,7 @@ public class Hbase { struct.rows = new ArrayList(_list228.size); for (int _i229 = 0; _i229 < _list228.size; ++_i229) { - ByteBuffer _elem230; // optional + ByteBuffer _elem230; // required _elem230 = iprot.readBinary(); struct.rows.add(_elem230); } @@ -23824,7 +24199,7 @@ public class Hbase { struct.columns = new ArrayList(_list231.size); for (int _i232 = 0; _i232 < _list231.size; ++_i232) { - ByteBuffer _elem233; // optional + ByteBuffer _elem233; // required _elem233 = iprot.readBinary(); struct.columns.add(_elem233); } @@ -23843,7 +24218,7 @@ public class Hbase { for (int _i235 = 0; _i235 < _map234.size; ++_i235) { ByteBuffer _key236; // required - ByteBuffer _val237; // required + ByteBuffer _val237; // optional _key236 = iprot.readBinary(); _val237 = iprot.readBinary(); struct.attributes.put(_key236, _val237); @@ -23990,7 +24365,7 @@ public class Hbase { struct.rows = new ArrayList(_list244.size); for (int _i245 = 0; _i245 < _list244.size; ++_i245) { - ByteBuffer _elem246; // optional + ByteBuffer _elem246; // required _elem246 = iprot.readBinary(); struct.rows.add(_elem246); } @@ -24003,7 +24378,7 @@ public class Hbase { struct.columns = new ArrayList(_list247.size); for (int _i248 = 0; _i248 < _list247.size; ++_i248) { - ByteBuffer _elem249; // optional + ByteBuffer _elem249; // required _elem249 = iprot.readBinary(); struct.columns.add(_elem249); } @@ -24017,7 +24392,7 @@ public class Hbase { for (int _i251 = 0; _i251 < _map250.size; ++_i251) { ByteBuffer _key252; // required - ByteBuffer _val253; // required + ByteBuffer _val253; // optional _key252 = iprot.readBinary(); _val253 = iprot.readBinary(); struct.attributes.put(_key252, _val253); @@ -24304,7 +24679,19 @@ public class Hbase { @Override public int hashCode() { - return 0; + HashCodeBuilder builder = new HashCodeBuilder(); + + boolean present_success = true && (isSetSuccess()); + builder.append(present_success); + if (present_success) + builder.append(success); + + boolean present_io = true && (isSetIo()); + builder.append(present_io); + if (present_io) + builder.append(io); + + return builder.toHashCode(); } public int compareTo(getRowsWithColumns_result other) { @@ -24419,7 +24806,7 @@ public class Hbase { struct.success = new ArrayList(_list254.size); for (int _i255 = 0; _i255 < _list254.size; ++_i255) { - TRowResult _elem256; // optional + TRowResult _elem256; // required _elem256 = new TRowResult(); _elem256.read(iprot); struct.success.add(_elem256); @@ -24521,7 +24908,7 @@ public class Hbase { struct.success = new ArrayList(_list259.size); for (int _i260 = 0; _i260 < _list259.size; ++_i260) { - TRowResult _elem261; // optional + TRowResult _elem261; // required _elem261 = new TRowResult(); _elem261.read(iprot); struct.success.add(_elem261); @@ -25017,7 +25404,29 @@ public class Hbase { @Override public int hashCode() { - return 0; + HashCodeBuilder builder = new HashCodeBuilder(); + + boolean present_tableName = true && (isSetTableName()); + builder.append(present_tableName); + if (present_tableName) + builder.append(tableName); + + boolean present_rows = true && (isSetRows()); + builder.append(present_rows); + if (present_rows) + builder.append(rows); + + boolean present_timestamp = true; + builder.append(present_timestamp); + if (present_timestamp) + builder.append(timestamp); + + boolean present_attributes = true && (isSetAttributes()); + builder.append(present_attributes); + if (present_attributes) + builder.append(attributes); + + return builder.toHashCode(); } public int compareTo(getRowsTs_args other) { @@ -25174,7 +25583,7 @@ public class Hbase { struct.rows = new ArrayList(_list262.size); for (int _i263 = 0; _i263 < _list262.size; ++_i263) { - ByteBuffer _elem264; // optional + ByteBuffer _elem264; // required _elem264 = iprot.readBinary(); struct.rows.add(_elem264); } @@ -25201,7 +25610,7 @@ public class Hbase { for (int _i266 = 0; _i266 < _map265.size; ++_i266) { ByteBuffer _key267; // required - ByteBuffer _val268; // required + ByteBuffer _val268; // optional _key267 = iprot.readBinary(); _val268 = iprot.readBinary(); struct.attributes.put(_key267, _val268); @@ -25333,7 +25742,7 @@ public class Hbase { struct.rows = new ArrayList(_list273.size); for (int _i274 = 0; _i274 < _list273.size; ++_i274) { - ByteBuffer _elem275; // optional + ByteBuffer _elem275; // required _elem275 = iprot.readBinary(); struct.rows.add(_elem275); } @@ -25351,7 +25760,7 @@ public class Hbase { for (int _i277 = 0; _i277 < _map276.size; ++_i277) { ByteBuffer _key278; // required - ByteBuffer _val279; // required + ByteBuffer _val279; // optional _key278 = iprot.readBinary(); _val279 = iprot.readBinary(); struct.attributes.put(_key278, _val279); @@ -25638,7 +26047,19 @@ public class Hbase { @Override public int hashCode() { - return 0; + HashCodeBuilder builder = new HashCodeBuilder(); + + boolean present_success = true && (isSetSuccess()); + builder.append(present_success); + if (present_success) + builder.append(success); + + boolean present_io = true && (isSetIo()); + builder.append(present_io); + if (present_io) + builder.append(io); + + return builder.toHashCode(); } public int compareTo(getRowsTs_result other) { @@ -25753,7 +26174,7 @@ public class Hbase { struct.success = new ArrayList(_list280.size); for (int _i281 = 0; _i281 < _list280.size; ++_i281) { - TRowResult _elem282; // optional + TRowResult _elem282; // required _elem282 = new TRowResult(); _elem282.read(iprot); struct.success.add(_elem282); @@ -25855,7 +26276,7 @@ public class Hbase { struct.success = new ArrayList(_list285.size); for (int _i286 = 0; _i286 < _list285.size; ++_i286) { - TRowResult _elem287; // optional + TRowResult _elem287; // required _elem287 = new TRowResult(); _elem287.read(iprot); struct.success.add(_elem287); @@ -26430,7 +26851,34 @@ public class Hbase { @Override public int hashCode() { - return 0; + HashCodeBuilder builder = new HashCodeBuilder(); + + boolean present_tableName = true && (isSetTableName()); + builder.append(present_tableName); + if (present_tableName) + builder.append(tableName); + + boolean present_rows = true && (isSetRows()); + builder.append(present_rows); + if (present_rows) + builder.append(rows); + + boolean present_columns = true && (isSetColumns()); + builder.append(present_columns); + if (present_columns) + builder.append(columns); + + boolean present_timestamp = true; + builder.append(present_timestamp); + if (present_timestamp) + builder.append(timestamp); + + boolean present_attributes = true && (isSetAttributes()); + builder.append(present_attributes); + if (present_attributes) + builder.append(attributes); + + return builder.toHashCode(); } public int compareTo(getRowsWithColumnsTs_args other) { @@ -26605,7 +27053,7 @@ public class Hbase { struct.rows = new ArrayList(_list288.size); for (int _i289 = 0; _i289 < _list288.size; ++_i289) { - ByteBuffer _elem290; // optional + ByteBuffer _elem290; // required _elem290 = iprot.readBinary(); struct.rows.add(_elem290); } @@ -26623,7 +27071,7 @@ public class Hbase { struct.columns = new ArrayList(_list291.size); for (int _i292 = 0; _i292 < _list291.size; ++_i292) { - ByteBuffer _elem293; // optional + ByteBuffer _elem293; // required _elem293 = iprot.readBinary(); struct.columns.add(_elem293); } @@ -26650,7 +27098,7 @@ public class Hbase { for (int _i295 = 0; _i295 < _map294.size; ++_i295) { ByteBuffer _key296; // required - ByteBuffer _val297; // required + ByteBuffer _val297; // optional _key296 = iprot.readBinary(); _val297 = iprot.readBinary(); struct.attributes.put(_key296, _val297); @@ -26806,7 +27254,7 @@ public class Hbase { struct.rows = new ArrayList(_list304.size); for (int _i305 = 0; _i305 < _list304.size; ++_i305) { - ByteBuffer _elem306; // optional + ByteBuffer _elem306; // required _elem306 = iprot.readBinary(); struct.rows.add(_elem306); } @@ -26819,7 +27267,7 @@ public class Hbase { struct.columns = new ArrayList(_list307.size); for (int _i308 = 0; _i308 < _list307.size; ++_i308) { - ByteBuffer _elem309; // optional + ByteBuffer _elem309; // required _elem309 = iprot.readBinary(); struct.columns.add(_elem309); } @@ -26837,7 +27285,7 @@ public class Hbase { for (int _i311 = 0; _i311 < _map310.size; ++_i311) { ByteBuffer _key312; // required - ByteBuffer _val313; // required + ByteBuffer _val313; // optional _key312 = iprot.readBinary(); _val313 = iprot.readBinary(); struct.attributes.put(_key312, _val313); @@ -27124,7 +27572,19 @@ public class Hbase { @Override public int hashCode() { - return 0; + HashCodeBuilder builder = new HashCodeBuilder(); + + boolean present_success = true && (isSetSuccess()); + builder.append(present_success); + if (present_success) + builder.append(success); + + boolean present_io = true && (isSetIo()); + builder.append(present_io); + if (present_io) + builder.append(io); + + return builder.toHashCode(); } public int compareTo(getRowsWithColumnsTs_result other) { @@ -27239,7 +27699,7 @@ public class Hbase { struct.success = new ArrayList(_list314.size); for (int _i315 = 0; _i315 < _list314.size; ++_i315) { - TRowResult _elem316; // optional + TRowResult _elem316; // required _elem316 = new TRowResult(); _elem316.read(iprot); struct.success.add(_elem316); @@ -27341,7 +27801,7 @@ public class Hbase { struct.success = new ArrayList(_list319.size); for (int _i320 = 0; _i320 < _list319.size; ++_i320) { - TRowResult _elem321; // optional + TRowResult _elem321; // required _elem321 = new TRowResult(); _elem321.read(iprot); struct.success.add(_elem321); @@ -27386,7 +27846,7 @@ public class Hbase { */ public List mutations; // required /** - * Put attributes + * Mutation attributes */ public Map attributes; // required @@ -27405,7 +27865,7 @@ public class Hbase { */ MUTATIONS((short)3, "mutations"), /** - * Put attributes + * Mutation attributes */ ATTRIBUTES((short)4, "attributes"); @@ -27687,14 +28147,14 @@ public class Hbase { } /** - * Put attributes + * Mutation attributes */ public Map getAttributes() { return this.attributes; } /** - * Put attributes + * Mutation attributes */ public mutateRow_args setAttributes(Map attributes) { this.attributes = attributes; @@ -27844,7 +28304,29 @@ public class Hbase { @Override public int hashCode() { - return 0; + HashCodeBuilder builder = new HashCodeBuilder(); + + boolean present_tableName = true && (isSetTableName()); + builder.append(present_tableName); + if (present_tableName) + builder.append(tableName); + + boolean present_row = true && (isSetRow()); + builder.append(present_row); + if (present_row) + builder.append(row); + + boolean present_mutations = true && (isSetMutations()); + builder.append(present_mutations); + if (present_mutations) + builder.append(mutations); + + boolean present_attributes = true && (isSetAttributes()); + builder.append(present_attributes); + if (present_attributes) + builder.append(attributes); + + return builder.toHashCode(); } public int compareTo(mutateRow_args other) { @@ -28011,7 +28493,7 @@ public class Hbase { struct.mutations = new ArrayList(_list322.size); for (int _i323 = 0; _i323 < _list322.size; ++_i323) { - Mutation _elem324; // optional + Mutation _elem324; // required _elem324 = new Mutation(); _elem324.read(iprot); struct.mutations.add(_elem324); @@ -28031,7 +28513,7 @@ public class Hbase { for (int _i326 = 0; _i326 < _map325.size; ++_i326) { ByteBuffer _key327; // required - ByteBuffer _val328; // required + ByteBuffer _val328; // optional _key327 = iprot.readBinary(); _val328 = iprot.readBinary(); struct.attributes.put(_key327, _val328); @@ -28169,7 +28651,7 @@ public class Hbase { struct.mutations = new ArrayList(_list333.size); for (int _i334 = 0; _i334 < _list333.size; ++_i334) { - Mutation _elem335; // optional + Mutation _elem335; // required _elem335 = new Mutation(); _elem335.read(iprot); struct.mutations.add(_elem335); @@ -28184,7 +28666,7 @@ public class Hbase { for (int _i337 = 0; _i337 < _map336.size; ++_i337) { ByteBuffer _key338; // required - ByteBuffer _val339; // required + ByteBuffer _val339; // optional _key338 = iprot.readBinary(); _val339 = iprot.readBinary(); struct.attributes.put(_key338, _val339); @@ -28451,7 +28933,19 @@ public class Hbase { @Override public int hashCode() { - return 0; + HashCodeBuilder builder = new HashCodeBuilder(); + + boolean present_io = true && (isSetIo()); + builder.append(present_io); + if (present_io) + builder.append(io); + + boolean present_ia = true && (isSetIa()); + builder.append(present_ia); + if (present_ia) + builder.append(ia); + + return builder.toHashCode(); } public int compareTo(mutateRow_result other) { @@ -28686,7 +29180,7 @@ public class Hbase { */ public long timestamp; // required /** - * Put attributes + * Mutation attributes */ public Map attributes; // required @@ -28709,7 +29203,7 @@ public class Hbase { */ TIMESTAMP((short)4, "timestamp"), /** - * Put attributes + * Mutation attributes */ ATTRIBUTES((short)5, "attributes"); @@ -29034,14 +29528,14 @@ public class Hbase { } /** - * Put attributes + * Mutation attributes */ public Map getAttributes() { return this.attributes; } /** - * Put attributes + * Mutation attributes */ public mutateRowTs_args setAttributes(Map attributes) { this.attributes = attributes; @@ -29213,7 +29707,34 @@ public class Hbase { @Override public int hashCode() { - return 0; + HashCodeBuilder builder = new HashCodeBuilder(); + + boolean present_tableName = true && (isSetTableName()); + builder.append(present_tableName); + if (present_tableName) + builder.append(tableName); + + boolean present_row = true && (isSetRow()); + builder.append(present_row); + if (present_row) + builder.append(row); + + boolean present_mutations = true && (isSetMutations()); + builder.append(present_mutations); + if (present_mutations) + builder.append(mutations); + + boolean present_timestamp = true; + builder.append(present_timestamp); + if (present_timestamp) + builder.append(timestamp); + + boolean present_attributes = true && (isSetAttributes()); + builder.append(present_attributes); + if (present_attributes) + builder.append(attributes); + + return builder.toHashCode(); } public int compareTo(mutateRowTs_args other) { @@ -29396,7 +29917,7 @@ public class Hbase { struct.mutations = new ArrayList(_list340.size); for (int _i341 = 0; _i341 < _list340.size; ++_i341) { - Mutation _elem342; // optional + Mutation _elem342; // required _elem342 = new Mutation(); _elem342.read(iprot); struct.mutations.add(_elem342); @@ -29424,7 +29945,7 @@ public class Hbase { for (int _i344 = 0; _i344 < _map343.size; ++_i344) { ByteBuffer _key345; // required - ByteBuffer _val346; // required + ByteBuffer _val346; // optional _key345 = iprot.readBinary(); _val346 = iprot.readBinary(); struct.attributes.put(_key345, _val346); @@ -29571,7 +30092,7 @@ public class Hbase { struct.mutations = new ArrayList(_list351.size); for (int _i352 = 0; _i352 < _list351.size; ++_i352) { - Mutation _elem353; // optional + Mutation _elem353; // required _elem353 = new Mutation(); _elem353.read(iprot); struct.mutations.add(_elem353); @@ -29590,7 +30111,7 @@ public class Hbase { for (int _i355 = 0; _i355 < _map354.size; ++_i355) { ByteBuffer _key356; // required - ByteBuffer _val357; // required + ByteBuffer _val357; // optional _key356 = iprot.readBinary(); _val357 = iprot.readBinary(); struct.attributes.put(_key356, _val357); @@ -29857,7 +30378,19 @@ public class Hbase { @Override public int hashCode() { - return 0; + HashCodeBuilder builder = new HashCodeBuilder(); + + boolean present_io = true && (isSetIo()); + builder.append(present_io); + if (present_io) + builder.append(io); + + boolean present_ia = true && (isSetIa()); + builder.append(present_ia); + if (present_ia) + builder.append(ia); + + return builder.toHashCode(); } public int compareTo(mutateRowTs_result other) { @@ -30082,7 +30615,7 @@ public class Hbase { */ public List rowBatches; // required /** - * Put attributes + * Mutation attributes */ public Map attributes; // required @@ -30097,7 +30630,7 @@ public class Hbase { */ ROW_BATCHES((short)2, "rowBatches"), /** - * Put attributes + * Mutation attributes */ ATTRIBUTES((short)3, "attributes"); @@ -30329,14 +30862,14 @@ public class Hbase { } /** - * Put attributes + * Mutation attributes */ public Map getAttributes() { return this.attributes; } /** - * Put attributes + * Mutation attributes */ public mutateRows_args setAttributes(Map attributes) { this.attributes = attributes; @@ -30464,7 +30997,24 @@ public class Hbase { @Override public int hashCode() { - return 0; + HashCodeBuilder builder = new HashCodeBuilder(); + + boolean present_tableName = true && (isSetTableName()); + builder.append(present_tableName); + if (present_tableName) + builder.append(tableName); + + boolean present_rowBatches = true && (isSetRowBatches()); + builder.append(present_rowBatches); + if (present_rowBatches) + builder.append(rowBatches); + + boolean present_attributes = true && (isSetAttributes()); + builder.append(present_attributes); + if (present_attributes) + builder.append(attributes); + + return builder.toHashCode(); } public int compareTo(mutateRows_args other) { @@ -30605,7 +31155,7 @@ public class Hbase { struct.rowBatches = new ArrayList(_list358.size); for (int _i359 = 0; _i359 < _list358.size; ++_i359) { - BatchMutation _elem360; // optional + BatchMutation _elem360; // required _elem360 = new BatchMutation(); _elem360.read(iprot); struct.rowBatches.add(_elem360); @@ -30625,7 +31175,7 @@ public class Hbase { for (int _i362 = 0; _i362 < _map361.size; ++_i362) { ByteBuffer _key363; // required - ByteBuffer _val364; // required + ByteBuffer _val364; // optional _key363 = iprot.readBinary(); _val364 = iprot.readBinary(); struct.attributes.put(_key363, _val364); @@ -30748,7 +31298,7 @@ public class Hbase { struct.rowBatches = new ArrayList(_list369.size); for (int _i370 = 0; _i370 < _list369.size; ++_i370) { - BatchMutation _elem371; // optional + BatchMutation _elem371; // required _elem371 = new BatchMutation(); _elem371.read(iprot); struct.rowBatches.add(_elem371); @@ -30763,7 +31313,7 @@ public class Hbase { for (int _i373 = 0; _i373 < _map372.size; ++_i373) { ByteBuffer _key374; // required - ByteBuffer _val375; // required + ByteBuffer _val375; // optional _key374 = iprot.readBinary(); _val375 = iprot.readBinary(); struct.attributes.put(_key374, _val375); @@ -31030,7 +31580,19 @@ public class Hbase { @Override public int hashCode() { - return 0; + HashCodeBuilder builder = new HashCodeBuilder(); + + boolean present_io = true && (isSetIo()); + builder.append(present_io); + if (present_io) + builder.append(io); + + boolean present_ia = true && (isSetIa()); + builder.append(present_ia); + if (present_ia) + builder.append(ia); + + return builder.toHashCode(); } public int compareTo(mutateRows_result other) { @@ -31260,7 +31822,7 @@ public class Hbase { */ public long timestamp; // required /** - * Put attributes + * Mutation attributes */ public Map attributes; // required @@ -31279,7 +31841,7 @@ public class Hbase { */ TIMESTAMP((short)3, "timestamp"), /** - * Put attributes + * Mutation attributes */ ATTRIBUTES((short)4, "attributes"); @@ -31554,14 +32116,14 @@ public class Hbase { } /** - * Put attributes + * Mutation attributes */ public Map getAttributes() { return this.attributes; } /** - * Put attributes + * Mutation attributes */ public mutateRowsTs_args setAttributes(Map attributes) { this.attributes = attributes; @@ -31711,7 +32273,29 @@ public class Hbase { @Override public int hashCode() { - return 0; + HashCodeBuilder builder = new HashCodeBuilder(); + + boolean present_tableName = true && (isSetTableName()); + builder.append(present_tableName); + if (present_tableName) + builder.append(tableName); + + boolean present_rowBatches = true && (isSetRowBatches()); + builder.append(present_rowBatches); + if (present_rowBatches) + builder.append(rowBatches); + + boolean present_timestamp = true; + builder.append(present_timestamp); + if (present_timestamp) + builder.append(timestamp); + + boolean present_attributes = true && (isSetAttributes()); + builder.append(present_attributes); + if (present_attributes) + builder.append(attributes); + + return builder.toHashCode(); } public int compareTo(mutateRowsTs_args other) { @@ -31866,7 +32450,7 @@ public class Hbase { struct.rowBatches = new ArrayList(_list376.size); for (int _i377 = 0; _i377 < _list376.size; ++_i377) { - BatchMutation _elem378; // optional + BatchMutation _elem378; // required _elem378 = new BatchMutation(); _elem378.read(iprot); struct.rowBatches.add(_elem378); @@ -31894,7 +32478,7 @@ public class Hbase { for (int _i380 = 0; _i380 < _map379.size; ++_i380) { ByteBuffer _key381; // required - ByteBuffer _val382; // required + ByteBuffer _val382; // optional _key381 = iprot.readBinary(); _val382 = iprot.readBinary(); struct.attributes.put(_key381, _val382); @@ -32026,7 +32610,7 @@ public class Hbase { struct.rowBatches = new ArrayList(_list387.size); for (int _i388 = 0; _i388 < _list387.size; ++_i388) { - BatchMutation _elem389; // optional + BatchMutation _elem389; // required _elem389 = new BatchMutation(); _elem389.read(iprot); struct.rowBatches.add(_elem389); @@ -32045,7 +32629,7 @@ public class Hbase { for (int _i391 = 0; _i391 < _map390.size; ++_i391) { ByteBuffer _key392; // required - ByteBuffer _val393; // required + ByteBuffer _val393; // optional _key392 = iprot.readBinary(); _val393 = iprot.readBinary(); struct.attributes.put(_key392, _val393); @@ -32312,7 +32896,19 @@ public class Hbase { @Override public int hashCode() { - return 0; + HashCodeBuilder builder = new HashCodeBuilder(); + + boolean present_io = true && (isSetIo()); + builder.append(present_io); + if (present_io) + builder.append(io); + + boolean present_ia = true && (isSetIa()); + builder.append(present_ia); + if (present_ia) + builder.append(ia); + + return builder.toHashCode(); } public int compareTo(mutateRowsTs_result other) { @@ -32968,7 +33564,29 @@ public class Hbase { @Override public int hashCode() { - return 0; + HashCodeBuilder builder = new HashCodeBuilder(); + + boolean present_tableName = true && (isSetTableName()); + builder.append(present_tableName); + if (present_tableName) + builder.append(tableName); + + boolean present_row = true && (isSetRow()); + builder.append(present_row); + if (present_row) + builder.append(row); + + boolean present_column = true && (isSetColumn()); + builder.append(present_column); + if (present_column) + builder.append(column); + + boolean present_value = true; + builder.append(present_value); + if (present_value) + builder.append(value); + + return builder.toHashCode(); } public int compareTo(atomicIncrement_args other) { @@ -33561,7 +34179,24 @@ public class Hbase { @Override public int hashCode() { - return 0; + HashCodeBuilder builder = new HashCodeBuilder(); + + boolean present_success = true; + builder.append(present_success); + if (present_success) + builder.append(success); + + boolean present_io = true && (isSetIo()); + builder.append(present_io); + if (present_io) + builder.append(io); + + boolean present_ia = true && (isSetIa()); + builder.append(present_ia); + if (present_ia) + builder.append(ia); + + return builder.toHashCode(); } public int compareTo(atomicIncrement_result other) { @@ -33659,6 +34294,8 @@ public class Hbase { private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException { try { + // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor. + __isset_bit_vector = new BitSet(1); read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in))); } catch (org.apache.thrift.TException te) { throw new java.io.IOException(te); @@ -34274,7 +34911,29 @@ public class Hbase { @Override public int hashCode() { - return 0; + HashCodeBuilder builder = new HashCodeBuilder(); + + boolean present_tableName = true && (isSetTableName()); + builder.append(present_tableName); + if (present_tableName) + builder.append(tableName); + + boolean present_row = true && (isSetRow()); + builder.append(present_row); + if (present_row) + builder.append(row); + + boolean present_column = true && (isSetColumn()); + builder.append(present_column); + if (present_column) + builder.append(column); + + boolean present_attributes = true && (isSetAttributes()); + builder.append(present_attributes); + if (present_attributes) + builder.append(attributes); + + return builder.toHashCode(); } public int compareTo(deleteAll_args other) { @@ -34450,7 +35109,7 @@ public class Hbase { for (int _i395 = 0; _i395 < _map394.size; ++_i395) { ByteBuffer _key396; // required - ByteBuffer _val397; // required + ByteBuffer _val397; // optional _key396 = iprot.readBinary(); _val397 = iprot.readBinary(); struct.attributes.put(_key396, _val397); @@ -34580,7 +35239,7 @@ public class Hbase { for (int _i401 = 0; _i401 < _map400.size; ++_i401) { ByteBuffer _key402; // required - ByteBuffer _val403; // required + ByteBuffer _val403; // optional _key402 = iprot.readBinary(); _val403 = iprot.readBinary(); struct.attributes.put(_key402, _val403); @@ -34788,7 +35447,14 @@ public class Hbase { @Override public int hashCode() { - return 0; + HashCodeBuilder builder = new HashCodeBuilder(); + + boolean present_io = true && (isSetIo()); + builder.append(present_io); + if (present_io) + builder.append(io); + + return builder.toHashCode(); } public int compareTo(deleteAll_result other) { @@ -35497,7 +36163,34 @@ public class Hbase { @Override public int hashCode() { - return 0; + HashCodeBuilder builder = new HashCodeBuilder(); + + boolean present_tableName = true && (isSetTableName()); + builder.append(present_tableName); + if (present_tableName) + builder.append(tableName); + + boolean present_row = true && (isSetRow()); + builder.append(present_row); + if (present_row) + builder.append(row); + + boolean present_column = true && (isSetColumn()); + builder.append(present_column); + if (present_column) + builder.append(column); + + boolean present_timestamp = true; + builder.append(present_timestamp); + if (present_timestamp) + builder.append(timestamp); + + boolean present_attributes = true && (isSetAttributes()); + builder.append(present_attributes); + if (present_attributes) + builder.append(attributes); + + return builder.toHashCode(); } public int compareTo(deleteAllTs_args other) { @@ -35697,7 +36390,7 @@ public class Hbase { for (int _i405 = 0; _i405 < _map404.size; ++_i405) { ByteBuffer _key406; // required - ByteBuffer _val407; // required + ByteBuffer _val407; // optional _key406 = iprot.readBinary(); _val407 = iprot.readBinary(); struct.attributes.put(_key406, _val407); @@ -35840,7 +36533,7 @@ public class Hbase { for (int _i411 = 0; _i411 < _map410.size; ++_i411) { ByteBuffer _key412; // required - ByteBuffer _val413; // required + ByteBuffer _val413; // optional _key412 = iprot.readBinary(); _val413 = iprot.readBinary(); struct.attributes.put(_key412, _val413); @@ -36048,7 +36741,14 @@ public class Hbase { @Override public int hashCode() { - return 0; + HashCodeBuilder builder = new HashCodeBuilder(); + + boolean present_io = true && (isSetIo()); + builder.append(present_io); + if (present_io) + builder.append(io); + + return builder.toHashCode(); } public int compareTo(deleteAllTs_result other) { @@ -36602,7 +37302,24 @@ public class Hbase { @Override public int hashCode() { - return 0; + HashCodeBuilder builder = new HashCodeBuilder(); + + boolean present_tableName = true && (isSetTableName()); + builder.append(present_tableName); + if (present_tableName) + builder.append(tableName); + + boolean present_row = true && (isSetRow()); + builder.append(present_row); + if (present_row) + builder.append(row); + + boolean present_attributes = true && (isSetAttributes()); + builder.append(present_attributes); + if (present_attributes) + builder.append(attributes); + + return builder.toHashCode(); } public int compareTo(deleteAllRow_args other) { @@ -36752,7 +37469,7 @@ public class Hbase { for (int _i415 = 0; _i415 < _map414.size; ++_i415) { ByteBuffer _key416; // required - ByteBuffer _val417; // required + ByteBuffer _val417; // optional _key416 = iprot.readBinary(); _val417 = iprot.readBinary(); struct.attributes.put(_key416, _val417); @@ -36867,7 +37584,7 @@ public class Hbase { for (int _i421 = 0; _i421 < _map420.size; ++_i421) { ByteBuffer _key422; // required - ByteBuffer _val423; // required + ByteBuffer _val423; // optional _key422 = iprot.readBinary(); _val423 = iprot.readBinary(); struct.attributes.put(_key422, _val423); @@ -37075,7 +37792,14 @@ public class Hbase { @Override public int hashCode() { - return 0; + HashCodeBuilder builder = new HashCodeBuilder(); + + boolean present_io = true && (isSetIo()); + builder.append(present_io); + if (present_io) + builder.append(io); + + return builder.toHashCode(); } public int compareTo(deleteAllRow_result other) { @@ -37703,7 +38427,29 @@ public class Hbase { @Override public int hashCode() { - return 0; + HashCodeBuilder builder = new HashCodeBuilder(); + + boolean present_tableName = true && (isSetTableName()); + builder.append(present_tableName); + if (present_tableName) + builder.append(tableName); + + boolean present_row = true && (isSetRow()); + builder.append(present_row); + if (present_row) + builder.append(row); + + boolean present_timestamp = true; + builder.append(present_timestamp); + if (present_timestamp) + builder.append(timestamp); + + boolean present_attributes = true && (isSetAttributes()); + builder.append(present_attributes); + if (present_attributes) + builder.append(attributes); + + return builder.toHashCode(); } public int compareTo(deleteAllRowTs_args other) { @@ -37877,7 +38623,7 @@ public class Hbase { for (int _i425 = 0; _i425 < _map424.size; ++_i425) { ByteBuffer _key426; // required - ByteBuffer _val427; // required + ByteBuffer _val427; // optional _key426 = iprot.readBinary(); _val427 = iprot.readBinary(); struct.attributes.put(_key426, _val427); @@ -38005,7 +38751,7 @@ public class Hbase { for (int _i431 = 0; _i431 < _map430.size; ++_i431) { ByteBuffer _key432; // required - ByteBuffer _val433; // required + ByteBuffer _val433; // optional _key432 = iprot.readBinary(); _val433 = iprot.readBinary(); struct.attributes.put(_key432, _val433); @@ -38213,7 +38959,14 @@ public class Hbase { @Override public int hashCode() { - return 0; + HashCodeBuilder builder = new HashCodeBuilder(); + + boolean present_io = true && (isSetIo()); + builder.append(present_io); + if (present_io) + builder.append(io); + + return builder.toHashCode(); } public int compareTo(deleteAllRowTs_result other) { @@ -38757,7 +39510,24 @@ public class Hbase { @Override public int hashCode() { - return 0; + HashCodeBuilder builder = new HashCodeBuilder(); + + boolean present_tableName = true && (isSetTableName()); + builder.append(present_tableName); + if (present_tableName) + builder.append(tableName); + + boolean present_scan = true && (isSetScan()); + builder.append(present_scan); + if (present_scan) + builder.append(scan); + + boolean present_attributes = true && (isSetAttributes()); + builder.append(present_attributes); + if (present_attributes) + builder.append(attributes); + + return builder.toHashCode(); } public int compareTo(scannerOpenWithScan_args other) { @@ -38908,7 +39678,7 @@ public class Hbase { for (int _i435 = 0; _i435 < _map434.size; ++_i435) { ByteBuffer _key436; // required - ByteBuffer _val437; // required + ByteBuffer _val437; // optional _key436 = iprot.readBinary(); _val437 = iprot.readBinary(); struct.attributes.put(_key436, _val437); @@ -39024,7 +39794,7 @@ public class Hbase { for (int _i441 = 0; _i441 < _map440.size; ++_i441) { ByteBuffer _key442; // required - ByteBuffer _val443; // required + ByteBuffer _val443; // optional _key442 = iprot.readBinary(); _val443 = iprot.readBinary(); struct.attributes.put(_key442, _val443); @@ -39294,7 +40064,19 @@ public class Hbase { @Override public int hashCode() { - return 0; + HashCodeBuilder builder = new HashCodeBuilder(); + + boolean present_success = true; + builder.append(present_success); + if (present_success) + builder.append(success); + + boolean present_io = true && (isSetIo()); + builder.append(present_io); + if (present_io) + builder.append(io); + + return builder.toHashCode(); } public int compareTo(scannerOpenWithScan_result other) { @@ -39374,6 +40156,8 @@ public class Hbase { private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException { try { + // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor. + __isset_bit_vector = new BitSet(1); read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in))); } catch (org.apache.thrift.TException te) { throw new java.io.IOException(te); @@ -39986,7 +40770,29 @@ public class Hbase { @Override public int hashCode() { - return 0; + HashCodeBuilder builder = new HashCodeBuilder(); + + boolean present_tableName = true && (isSetTableName()); + builder.append(present_tableName); + if (present_tableName) + builder.append(tableName); + + boolean present_startRow = true && (isSetStartRow()); + builder.append(present_startRow); + if (present_startRow) + builder.append(startRow); + + boolean present_columns = true && (isSetColumns()); + builder.append(present_columns); + if (present_columns) + builder.append(columns); + + boolean present_attributes = true && (isSetAttributes()); + builder.append(present_attributes); + if (present_attributes) + builder.append(attributes); + + return builder.toHashCode(); } public int compareTo(scannerOpen_args other) { @@ -40153,7 +40959,7 @@ public class Hbase { struct.columns = new ArrayList(_list444.size); for (int _i445 = 0; _i445 < _list444.size; ++_i445) { - ByteBuffer _elem446; // optional + ByteBuffer _elem446; // required _elem446 = iprot.readBinary(); struct.columns.add(_elem446); } @@ -40172,7 +40978,7 @@ public class Hbase { for (int _i448 = 0; _i448 < _map447.size; ++_i448) { ByteBuffer _key449; // required - ByteBuffer _val450; // required + ByteBuffer _val450; // optional _key449 = iprot.readBinary(); _val450 = iprot.readBinary(); struct.attributes.put(_key449, _val450); @@ -40310,7 +41116,7 @@ public class Hbase { struct.columns = new ArrayList(_list455.size); for (int _i456 = 0; _i456 < _list455.size; ++_i456) { - ByteBuffer _elem457; // optional + ByteBuffer _elem457; // required _elem457 = iprot.readBinary(); struct.columns.add(_elem457); } @@ -40324,7 +41130,7 @@ public class Hbase { for (int _i459 = 0; _i459 < _map458.size; ++_i459) { ByteBuffer _key460; // required - ByteBuffer _val461; // required + ByteBuffer _val461; // optional _key460 = iprot.readBinary(); _val461 = iprot.readBinary(); struct.attributes.put(_key460, _val461); @@ -40594,7 +41400,19 @@ public class Hbase { @Override public int hashCode() { - return 0; + HashCodeBuilder builder = new HashCodeBuilder(); + + boolean present_success = true; + builder.append(present_success); + if (present_success) + builder.append(success); + + boolean present_io = true && (isSetIo()); + builder.append(present_io); + if (present_io) + builder.append(io); + + return builder.toHashCode(); } public int compareTo(scannerOpen_result other) { @@ -40674,6 +41492,8 @@ public class Hbase { private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException { try { + // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor. + __isset_bit_vector = new BitSet(1); read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in))); } catch (org.apache.thrift.TException te) { throw new java.io.IOException(te); @@ -41371,7 +42191,34 @@ public class Hbase { @Override public int hashCode() { - return 0; + HashCodeBuilder builder = new HashCodeBuilder(); + + boolean present_tableName = true && (isSetTableName()); + builder.append(present_tableName); + if (present_tableName) + builder.append(tableName); + + boolean present_startRow = true && (isSetStartRow()); + builder.append(present_startRow); + if (present_startRow) + builder.append(startRow); + + boolean present_stopRow = true && (isSetStopRow()); + builder.append(present_stopRow); + if (present_stopRow) + builder.append(stopRow); + + boolean present_columns = true && (isSetColumns()); + builder.append(present_columns); + if (present_columns) + builder.append(columns); + + boolean present_attributes = true && (isSetAttributes()); + builder.append(present_attributes); + if (present_attributes) + builder.append(attributes); + + return builder.toHashCode(); } public int compareTo(scannerOpenWithStop_args other) { @@ -41564,7 +42411,7 @@ public class Hbase { struct.columns = new ArrayList(_list462.size); for (int _i463 = 0; _i463 < _list462.size; ++_i463) { - ByteBuffer _elem464; // optional + ByteBuffer _elem464; // required _elem464 = iprot.readBinary(); struct.columns.add(_elem464); } @@ -41583,7 +42430,7 @@ public class Hbase { for (int _i466 = 0; _i466 < _map465.size; ++_i466) { ByteBuffer _key467; // required - ByteBuffer _val468; // required + ByteBuffer _val468; // optional _key467 = iprot.readBinary(); _val468 = iprot.readBinary(); struct.attributes.put(_key467, _val468); @@ -41736,7 +42583,7 @@ public class Hbase { struct.columns = new ArrayList(_list473.size); for (int _i474 = 0; _i474 < _list473.size; ++_i474) { - ByteBuffer _elem475; // optional + ByteBuffer _elem475; // required _elem475 = iprot.readBinary(); struct.columns.add(_elem475); } @@ -41750,7 +42597,7 @@ public class Hbase { for (int _i477 = 0; _i477 < _map476.size; ++_i477) { ByteBuffer _key478; // required - ByteBuffer _val479; // required + ByteBuffer _val479; // optional _key478 = iprot.readBinary(); _val479 = iprot.readBinary(); struct.attributes.put(_key478, _val479); @@ -42020,7 +42867,19 @@ public class Hbase { @Override public int hashCode() { - return 0; + HashCodeBuilder builder = new HashCodeBuilder(); + + boolean present_success = true; + builder.append(present_success); + if (present_success) + builder.append(success); + + boolean present_io = true && (isSetIo()); + builder.append(present_io); + if (present_io) + builder.append(io); + + return builder.toHashCode(); } public int compareTo(scannerOpenWithStop_result other) { @@ -42100,6 +42959,8 @@ public class Hbase { private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException { try { + // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor. + __isset_bit_vector = new BitSet(1); read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in))); } catch (org.apache.thrift.TException te) { throw new java.io.IOException(te); @@ -42700,7 +43561,29 @@ public class Hbase { @Override public int hashCode() { - return 0; + HashCodeBuilder builder = new HashCodeBuilder(); + + boolean present_tableName = true && (isSetTableName()); + builder.append(present_tableName); + if (present_tableName) + builder.append(tableName); + + boolean present_startAndPrefix = true && (isSetStartAndPrefix()); + builder.append(present_startAndPrefix); + if (present_startAndPrefix) + builder.append(startAndPrefix); + + boolean present_columns = true && (isSetColumns()); + builder.append(present_columns); + if (present_columns) + builder.append(columns); + + boolean present_attributes = true && (isSetAttributes()); + builder.append(present_attributes); + if (present_attributes) + builder.append(attributes); + + return builder.toHashCode(); } public int compareTo(scannerOpenWithPrefix_args other) { @@ -42867,7 +43750,7 @@ public class Hbase { struct.columns = new ArrayList(_list480.size); for (int _i481 = 0; _i481 < _list480.size; ++_i481) { - ByteBuffer _elem482; // optional + ByteBuffer _elem482; // required _elem482 = iprot.readBinary(); struct.columns.add(_elem482); } @@ -42886,7 +43769,7 @@ public class Hbase { for (int _i484 = 0; _i484 < _map483.size; ++_i484) { ByteBuffer _key485; // required - ByteBuffer _val486; // required + ByteBuffer _val486; // optional _key485 = iprot.readBinary(); _val486 = iprot.readBinary(); struct.attributes.put(_key485, _val486); @@ -43024,7 +43907,7 @@ public class Hbase { struct.columns = new ArrayList(_list491.size); for (int _i492 = 0; _i492 < _list491.size; ++_i492) { - ByteBuffer _elem493; // optional + ByteBuffer _elem493; // required _elem493 = iprot.readBinary(); struct.columns.add(_elem493); } @@ -43038,7 +43921,7 @@ public class Hbase { for (int _i495 = 0; _i495 < _map494.size; ++_i495) { ByteBuffer _key496; // required - ByteBuffer _val497; // required + ByteBuffer _val497; // optional _key496 = iprot.readBinary(); _val497 = iprot.readBinary(); struct.attributes.put(_key496, _val497); @@ -43308,7 +44191,19 @@ public class Hbase { @Override public int hashCode() { - return 0; + HashCodeBuilder builder = new HashCodeBuilder(); + + boolean present_success = true; + builder.append(present_success); + if (present_success) + builder.append(success); + + boolean present_io = true && (isSetIo()); + builder.append(present_io); + if (present_io) + builder.append(io); + + return builder.toHashCode(); } public int compareTo(scannerOpenWithPrefix_result other) { @@ -43388,6 +44283,8 @@ public class Hbase { private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException { try { + // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor. + __isset_bit_vector = new BitSet(1); read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in))); } catch (org.apache.thrift.TException te) { throw new java.io.IOException(te); @@ -44074,7 +44971,34 @@ public class Hbase { @Override public int hashCode() { - return 0; + HashCodeBuilder builder = new HashCodeBuilder(); + + boolean present_tableName = true && (isSetTableName()); + builder.append(present_tableName); + if (present_tableName) + builder.append(tableName); + + boolean present_startRow = true && (isSetStartRow()); + builder.append(present_startRow); + if (present_startRow) + builder.append(startRow); + + boolean present_columns = true && (isSetColumns()); + builder.append(present_columns); + if (present_columns) + builder.append(columns); + + boolean present_timestamp = true; + builder.append(present_timestamp); + if (present_timestamp) + builder.append(timestamp); + + boolean present_attributes = true && (isSetAttributes()); + builder.append(present_attributes); + if (present_attributes) + builder.append(attributes); + + return builder.toHashCode(); } public int compareTo(scannerOpenTs_args other) { @@ -44255,7 +45179,7 @@ public class Hbase { struct.columns = new ArrayList(_list498.size); for (int _i499 = 0; _i499 < _list498.size; ++_i499) { - ByteBuffer _elem500; // optional + ByteBuffer _elem500; // required _elem500 = iprot.readBinary(); struct.columns.add(_elem500); } @@ -44282,7 +45206,7 @@ public class Hbase { for (int _i502 = 0; _i502 < _map501.size; ++_i502) { ByteBuffer _key503; // required - ByteBuffer _val504; // required + ByteBuffer _val504; // optional _key503 = iprot.readBinary(); _val504 = iprot.readBinary(); struct.attributes.put(_key503, _val504); @@ -44429,7 +45353,7 @@ public class Hbase { struct.columns = new ArrayList(_list509.size); for (int _i510 = 0; _i510 < _list509.size; ++_i510) { - ByteBuffer _elem511; // optional + ByteBuffer _elem511; // required _elem511 = iprot.readBinary(); struct.columns.add(_elem511); } @@ -44447,7 +45371,7 @@ public class Hbase { for (int _i513 = 0; _i513 < _map512.size; ++_i513) { ByteBuffer _key514; // required - ByteBuffer _val515; // required + ByteBuffer _val515; // optional _key514 = iprot.readBinary(); _val515 = iprot.readBinary(); struct.attributes.put(_key514, _val515); @@ -44717,7 +45641,19 @@ public class Hbase { @Override public int hashCode() { - return 0; + HashCodeBuilder builder = new HashCodeBuilder(); + + boolean present_success = true; + builder.append(present_success); + if (present_success) + builder.append(success); + + boolean present_io = true && (isSetIo()); + builder.append(present_io); + if (present_io) + builder.append(io); + + return builder.toHashCode(); } public int compareTo(scannerOpenTs_result other) { @@ -44797,6 +45733,8 @@ public class Hbase { private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException { try { + // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor. + __isset_bit_vector = new BitSet(1); read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in))); } catch (org.apache.thrift.TException te) { throw new java.io.IOException(te); @@ -45568,7 +46506,39 @@ public class Hbase { @Override public int hashCode() { - return 0; + HashCodeBuilder builder = new HashCodeBuilder(); + + boolean present_tableName = true && (isSetTableName()); + builder.append(present_tableName); + if (present_tableName) + builder.append(tableName); + + boolean present_startRow = true && (isSetStartRow()); + builder.append(present_startRow); + if (present_startRow) + builder.append(startRow); + + boolean present_stopRow = true && (isSetStopRow()); + builder.append(present_stopRow); + if (present_stopRow) + builder.append(stopRow); + + boolean present_columns = true && (isSetColumns()); + builder.append(present_columns); + if (present_columns) + builder.append(columns); + + boolean present_timestamp = true; + builder.append(present_timestamp); + if (present_timestamp) + builder.append(timestamp); + + boolean present_attributes = true && (isSetAttributes()); + builder.append(present_attributes); + if (present_attributes) + builder.append(attributes); + + return builder.toHashCode(); } public int compareTo(scannerOpenWithStopTs_args other) { @@ -45775,7 +46745,7 @@ public class Hbase { struct.columns = new ArrayList(_list516.size); for (int _i517 = 0; _i517 < _list516.size; ++_i517) { - ByteBuffer _elem518; // optional + ByteBuffer _elem518; // required _elem518 = iprot.readBinary(); struct.columns.add(_elem518); } @@ -45802,7 +46772,7 @@ public class Hbase { for (int _i520 = 0; _i520 < _map519.size; ++_i520) { ByteBuffer _key521; // required - ByteBuffer _val522; // required + ByteBuffer _val522; // optional _key521 = iprot.readBinary(); _val522 = iprot.readBinary(); struct.attributes.put(_key521, _val522); @@ -45964,7 +46934,7 @@ public class Hbase { struct.columns = new ArrayList(_list527.size); for (int _i528 = 0; _i528 < _list527.size; ++_i528) { - ByteBuffer _elem529; // optional + ByteBuffer _elem529; // required _elem529 = iprot.readBinary(); struct.columns.add(_elem529); } @@ -45982,7 +46952,7 @@ public class Hbase { for (int _i531 = 0; _i531 < _map530.size; ++_i531) { ByteBuffer _key532; // required - ByteBuffer _val533; // required + ByteBuffer _val533; // optional _key532 = iprot.readBinary(); _val533 = iprot.readBinary(); struct.attributes.put(_key532, _val533); @@ -46252,7 +47222,19 @@ public class Hbase { @Override public int hashCode() { - return 0; + HashCodeBuilder builder = new HashCodeBuilder(); + + boolean present_success = true; + builder.append(present_success); + if (present_success) + builder.append(success); + + boolean present_io = true && (isSetIo()); + builder.append(present_io); + if (present_io) + builder.append(io); + + return builder.toHashCode(); } public int compareTo(scannerOpenWithStopTs_result other) { @@ -46332,6 +47314,8 @@ public class Hbase { private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException { try { + // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor. + __isset_bit_vector = new BitSet(1); read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in))); } catch (org.apache.thrift.TException te) { throw new java.io.IOException(te); @@ -46657,7 +47641,14 @@ public class Hbase { @Override public int hashCode() { - return 0; + HashCodeBuilder builder = new HashCodeBuilder(); + + boolean present_id = true; + builder.append(present_id); + if (present_id) + builder.append(id); + + return builder.toHashCode(); } public int compareTo(scannerGet_args other) { @@ -47144,7 +48135,24 @@ public class Hbase { @Override public int hashCode() { - return 0; + HashCodeBuilder builder = new HashCodeBuilder(); + + boolean present_success = true && (isSetSuccess()); + builder.append(present_success); + if (present_success) + builder.append(success); + + boolean present_io = true && (isSetIo()); + builder.append(present_io); + if (present_io) + builder.append(io); + + boolean present_ia = true && (isSetIa()); + builder.append(present_ia); + if (present_ia) + builder.append(ia); + + return builder.toHashCode(); } public int compareTo(scannerGet_result other) { @@ -47277,7 +48285,7 @@ public class Hbase { struct.success = new ArrayList(_list534.size); for (int _i535 = 0; _i535 < _list534.size; ++_i535) { - TRowResult _elem536; // optional + TRowResult _elem536; // required _elem536 = new TRowResult(); _elem536.read(iprot); struct.success.add(_elem536); @@ -47399,7 +48407,7 @@ public class Hbase { struct.success = new ArrayList(_list539.size); for (int _i540 = 0; _i540 < _list539.size; ++_i540) { - TRowResult _elem541; // optional + TRowResult _elem541; // required _elem541 = new TRowResult(); _elem541.read(iprot); struct.success.add(_elem541); @@ -47703,7 +48711,19 @@ public class Hbase { @Override public int hashCode() { - return 0; + HashCodeBuilder builder = new HashCodeBuilder(); + + boolean present_id = true; + builder.append(present_id); + if (present_id) + builder.append(id); + + boolean present_nbRows = true; + builder.append(present_nbRows); + if (present_nbRows) + builder.append(nbRows); + + return builder.toHashCode(); } public int compareTo(scannerGetList_args other) { @@ -48223,7 +49243,24 @@ public class Hbase { @Override public int hashCode() { - return 0; + HashCodeBuilder builder = new HashCodeBuilder(); + + boolean present_success = true && (isSetSuccess()); + builder.append(present_success); + if (present_success) + builder.append(success); + + boolean present_io = true && (isSetIo()); + builder.append(present_io); + if (present_io) + builder.append(io); + + boolean present_ia = true && (isSetIa()); + builder.append(present_ia); + if (present_ia) + builder.append(ia); + + return builder.toHashCode(); } public int compareTo(scannerGetList_result other) { @@ -48356,7 +49393,7 @@ public class Hbase { struct.success = new ArrayList(_list542.size); for (int _i543 = 0; _i543 < _list542.size; ++_i543) { - TRowResult _elem544; // optional + TRowResult _elem544; // required _elem544 = new TRowResult(); _elem544.read(iprot); struct.success.add(_elem544); @@ -48478,7 +49515,7 @@ public class Hbase { struct.success = new ArrayList(_list547.size); for (int _i548 = 0; _i548 < _list547.size; ++_i548) { - TRowResult _elem549; // optional + TRowResult _elem549; // required _elem549 = new TRowResult(); _elem549.read(iprot); struct.success.add(_elem549); @@ -48711,7 +49748,14 @@ public class Hbase { @Override public int hashCode() { - return 0; + HashCodeBuilder builder = new HashCodeBuilder(); + + boolean present_id = true; + builder.append(present_id); + if (present_id) + builder.append(id); + + return builder.toHashCode(); } public int compareTo(scannerClose_args other) { @@ -49119,7 +50163,19 @@ public class Hbase { @Override public int hashCode() { - return 0; + HashCodeBuilder builder = new HashCodeBuilder(); + + boolean present_io = true && (isSetIo()); + builder.append(present_io); + if (present_io) + builder.append(io); + + boolean present_ia = true && (isSetIa()); + builder.append(present_ia); + if (present_ia) + builder.append(ia); + + return builder.toHashCode(); } public int compareTo(scannerClose_result other) { @@ -49322,46 +50378,28 @@ public class Hbase { } - public static class getRowOrBefore_args implements org.apache.thrift.TBase, java.io.Serializable, Cloneable { - private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getRowOrBefore_args"); + public static class getRegionInfo_args implements org.apache.thrift.TBase, java.io.Serializable, Cloneable { + private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getRegionInfo_args"); - private static final org.apache.thrift.protocol.TField TABLE_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("tableName", org.apache.thrift.protocol.TType.STRING, (short)1); - private static final org.apache.thrift.protocol.TField ROW_FIELD_DESC = new org.apache.thrift.protocol.TField("row", org.apache.thrift.protocol.TType.STRING, (short)2); - private static final org.apache.thrift.protocol.TField FAMILY_FIELD_DESC = new org.apache.thrift.protocol.TField("family", org.apache.thrift.protocol.TType.STRING, (short)3); + private static final org.apache.thrift.protocol.TField ROW_FIELD_DESC = new org.apache.thrift.protocol.TField("row", org.apache.thrift.protocol.TType.STRING, (short)1); private static final Map, SchemeFactory> schemes = new HashMap, SchemeFactory>(); static { - schemes.put(StandardScheme.class, new getRowOrBefore_argsStandardSchemeFactory()); - schemes.put(TupleScheme.class, new getRowOrBefore_argsTupleSchemeFactory()); + schemes.put(StandardScheme.class, new getRegionInfo_argsStandardSchemeFactory()); + schemes.put(TupleScheme.class, new getRegionInfo_argsTupleSchemeFactory()); } /** - * name of table - */ - public ByteBuffer tableName; // required - /** * row key */ public ByteBuffer row; // required - /** - * column name - */ - public ByteBuffer family; // required /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */ public enum _Fields implements org.apache.thrift.TFieldIdEnum { /** - * name of table - */ - TABLE_NAME((short)1, "tableName"), - /** * row key */ - ROW((short)2, "row"), - /** - * column name - */ - FAMILY((short)3, "family"); + ROW((short)1, "row"); private static final Map byName = new HashMap(); @@ -49376,12 +50414,8 @@ public class Hbase { */ public static _Fields findByThriftId(int fieldId) { switch(fieldId) { - case 1: // TABLE_NAME - return TABLE_NAME; - case 2: // ROW + case 1: // ROW return ROW; - case 3: // FAMILY - return FAMILY; default: return null; } @@ -49425,94 +50459,38 @@ public class Hbase { public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap; static { Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class); - tmpMap.put(_Fields.TABLE_NAME, new org.apache.thrift.meta_data.FieldMetaData("tableName", org.apache.thrift.TFieldRequirementType.DEFAULT, - new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING , "Text"))); tmpMap.put(_Fields.ROW, new org.apache.thrift.meta_data.FieldMetaData("row", org.apache.thrift.TFieldRequirementType.DEFAULT, new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING , "Text"))); - tmpMap.put(_Fields.FAMILY, new org.apache.thrift.meta_data.FieldMetaData("family", org.apache.thrift.TFieldRequirementType.DEFAULT, - new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING , "Text"))); metaDataMap = Collections.unmodifiableMap(tmpMap); - org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getRowOrBefore_args.class, metaDataMap); + org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getRegionInfo_args.class, metaDataMap); } - public getRowOrBefore_args() { + public getRegionInfo_args() { } - public getRowOrBefore_args( - ByteBuffer tableName, - ByteBuffer row, - ByteBuffer family) + public getRegionInfo_args( + ByteBuffer row) { this(); - this.tableName = tableName; this.row = row; - this.family = family; } /** * Performs a deep copy on other. */ - public getRowOrBefore_args(getRowOrBefore_args other) { - if (other.isSetTableName()) { - this.tableName = other.tableName; - } + public getRegionInfo_args(getRegionInfo_args other) { if (other.isSetRow()) { this.row = other.row; } - if (other.isSetFamily()) { - this.family = other.family; - } } - public getRowOrBefore_args deepCopy() { - return new getRowOrBefore_args(this); + public getRegionInfo_args deepCopy() { + return new getRegionInfo_args(this); } @Override public void clear() { - this.tableName = null; this.row = null; - this.family = null; - } - - /** - * name of table - */ - public byte[] getTableName() { - setTableName(org.apache.thrift.TBaseHelper.rightSize(tableName)); - return tableName == null ? null : tableName.array(); - } - - public ByteBuffer bufferForTableName() { - return tableName; - } - - /** - * name of table - */ - public getRowOrBefore_args setTableName(byte[] tableName) { - setTableName(tableName == null ? (ByteBuffer)null : ByteBuffer.wrap(tableName)); - return this; - } - - public getRowOrBefore_args setTableName(ByteBuffer tableName) { - this.tableName = tableName; - return this; - } - - public void unsetTableName() { - this.tableName = null; - } - - /** Returns true if field tableName is set (has been assigned a value) and false otherwise */ - public boolean isSetTableName() { - return this.tableName != null; - } - - public void setTableNameIsSet(boolean value) { - if (!value) { - this.tableName = null; - } } /** @@ -49530,12 +50508,12 @@ public class Hbase { /** * row key */ - public getRowOrBefore_args setRow(byte[] row) { + public getRegionInfo_args setRow(byte[] row) { setRow(row == null ? (ByteBuffer)null : ByteBuffer.wrap(row)); return this; } - public getRowOrBefore_args setRow(ByteBuffer row) { + public getRegionInfo_args setRow(ByteBuffer row) { this.row = row; return this; } @@ -49555,56 +50533,8 @@ public class Hbase { } } - /** - * column name - */ - public byte[] getFamily() { - setFamily(org.apache.thrift.TBaseHelper.rightSize(family)); - return family == null ? null : family.array(); - } - - public ByteBuffer bufferForFamily() { - return family; - } - - /** - * column name - */ - public getRowOrBefore_args setFamily(byte[] family) { - setFamily(family == null ? (ByteBuffer)null : ByteBuffer.wrap(family)); - return this; - } - - public getRowOrBefore_args setFamily(ByteBuffer family) { - this.family = family; - return this; - } - - public void unsetFamily() { - this.family = null; - } - - /** Returns true if field family is set (has been assigned a value) and false otherwise */ - public boolean isSetFamily() { - return this.family != null; - } - - public void setFamilyIsSet(boolean value) { - if (!value) { - this.family = null; - } - } - public void setFieldValue(_Fields field, Object value) { switch (field) { - case TABLE_NAME: - if (value == null) { - unsetTableName(); - } else { - setTableName((ByteBuffer)value); - } - break; - case ROW: if (value == null) { unsetRow(); @@ -49613,28 +50543,14 @@ public class Hbase { } break; - case FAMILY: - if (value == null) { - unsetFamily(); - } else { - setFamily((ByteBuffer)value); - } - break; - } } public Object getFieldValue(_Fields field) { switch (field) { - case TABLE_NAME: - return getTableName(); - case ROW: return getRow(); - case FAMILY: - return getFamily(); - } throw new IllegalStateException(); } @@ -49646,12 +50562,8 @@ public class Hbase { } switch (field) { - case TABLE_NAME: - return isSetTableName(); case ROW: return isSetRow(); - case FAMILY: - return isSetFamily(); } throw new IllegalStateException(); } @@ -49660,24 +50572,15 @@ public class Hbase { public boolean equals(Object that) { if (that == null) return false; - if (that instanceof getRowOrBefore_args) - return this.equals((getRowOrBefore_args)that); + if (that instanceof getRegionInfo_args) + return this.equals((getRegionInfo_args)that); return false; } - public boolean equals(getRowOrBefore_args that) { + public boolean equals(getRegionInfo_args that) { if (that == null) return false; - boolean this_present_tableName = true && this.isSetTableName(); - boolean that_present_tableName = true && that.isSetTableName(); - if (this_present_tableName || that_present_tableName) { - if (!(this_present_tableName && that_present_tableName)) - return false; - if (!this.tableName.equals(that.tableName)) - return false; - } - boolean this_present_row = true && this.isSetRow(); boolean that_present_row = true && that.isSetRow(); if (this_present_row || that_present_row) { @@ -49687,41 +50590,29 @@ public class Hbase { return false; } - boolean this_present_family = true && this.isSetFamily(); - boolean that_present_family = true && that.isSetFamily(); - if (this_present_family || that_present_family) { - if (!(this_present_family && that_present_family)) - return false; - if (!this.family.equals(that.family)) - return false; - } - return true; } @Override public int hashCode() { - return 0; + HashCodeBuilder builder = new HashCodeBuilder(); + + boolean present_row = true && (isSetRow()); + builder.append(present_row); + if (present_row) + builder.append(row); + + return builder.toHashCode(); } - public int compareTo(getRowOrBefore_args other) { + public int compareTo(getRegionInfo_args other) { if (!getClass().equals(other.getClass())) { return getClass().getName().compareTo(other.getClass().getName()); } int lastComparison = 0; - getRowOrBefore_args typedOther = (getRowOrBefore_args)other; + getRegionInfo_args typedOther = (getRegionInfo_args)other; - lastComparison = Boolean.valueOf(isSetTableName()).compareTo(typedOther.isSetTableName()); - if (lastComparison != 0) { - return lastComparison; - } - if (isSetTableName()) { - lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.tableName, typedOther.tableName); - if (lastComparison != 0) { - return lastComparison; - } - } lastComparison = Boolean.valueOf(isSetRow()).compareTo(typedOther.isSetRow()); if (lastComparison != 0) { return lastComparison; @@ -49732,16 +50623,6 @@ public class Hbase { return lastComparison; } } - lastComparison = Boolean.valueOf(isSetFamily()).compareTo(typedOther.isSetFamily()); - if (lastComparison != 0) { - return lastComparison; - } - if (isSetFamily()) { - lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.family, typedOther.family); - if (lastComparison != 0) { - return lastComparison; - } - } return 0; } @@ -49759,953 +50640,7 @@ public class Hbase { @Override public String toString() { - StringBuilder sb = new StringBuilder("getRowOrBefore_args("); - boolean first = true; - - sb.append("tableName:"); - if (this.tableName == null) { - sb.append("null"); - } else { - sb.append(this.tableName); - } - first = false; - if (!first) sb.append(", "); - sb.append("row:"); - if (this.row == null) { - sb.append("null"); - } else { - sb.append(this.row); - } - first = false; - if (!first) sb.append(", "); - sb.append("family:"); - if (this.family == null) { - sb.append("null"); - } else { - sb.append(this.family); - } - first = false; - sb.append(")"); - return sb.toString(); - } - - public void validate() throws org.apache.thrift.TException { - // check for required fields - } - - private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException { - try { - write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out))); - } catch (org.apache.thrift.TException te) { - throw new java.io.IOException(te); - } - } - - private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException { - try { - read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in))); - } catch (org.apache.thrift.TException te) { - throw new java.io.IOException(te); - } - } - - private static class getRowOrBefore_argsStandardSchemeFactory implements SchemeFactory { - public getRowOrBefore_argsStandardScheme getScheme() { - return new getRowOrBefore_argsStandardScheme(); - } - } - - private static class getRowOrBefore_argsStandardScheme extends StandardScheme { - - public void read(org.apache.thrift.protocol.TProtocol iprot, getRowOrBefore_args struct) throws org.apache.thrift.TException { - org.apache.thrift.protocol.TField schemeField; - iprot.readStructBegin(); - while (true) - { - schemeField = iprot.readFieldBegin(); - if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { - break; - } - switch (schemeField.id) { - case 1: // TABLE_NAME - if (schemeField.type == org.apache.thrift.protocol.TType.STRING) { - struct.tableName = iprot.readBinary(); - struct.setTableNameIsSet(true); - } else { - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - break; - case 2: // ROW - if (schemeField.type == org.apache.thrift.protocol.TType.STRING) { - struct.row = iprot.readBinary(); - struct.setRowIsSet(true); - } else { - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - break; - case 3: // FAMILY - if (schemeField.type == org.apache.thrift.protocol.TType.STRING) { - struct.family = iprot.readBinary(); - struct.setFamilyIsSet(true); - } else { - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - break; - default: - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - iprot.readFieldEnd(); - } - iprot.readStructEnd(); - - // check for required fields of primitive type, which can't be checked in the validate method - struct.validate(); - } - - public void write(org.apache.thrift.protocol.TProtocol oprot, getRowOrBefore_args struct) throws org.apache.thrift.TException { - struct.validate(); - - oprot.writeStructBegin(STRUCT_DESC); - if (struct.tableName != null) { - oprot.writeFieldBegin(TABLE_NAME_FIELD_DESC); - oprot.writeBinary(struct.tableName); - oprot.writeFieldEnd(); - } - if (struct.row != null) { - oprot.writeFieldBegin(ROW_FIELD_DESC); - oprot.writeBinary(struct.row); - oprot.writeFieldEnd(); - } - if (struct.family != null) { - oprot.writeFieldBegin(FAMILY_FIELD_DESC); - oprot.writeBinary(struct.family); - oprot.writeFieldEnd(); - } - oprot.writeFieldStop(); - oprot.writeStructEnd(); - } - - } - - private static class getRowOrBefore_argsTupleSchemeFactory implements SchemeFactory { - public getRowOrBefore_argsTupleScheme getScheme() { - return new getRowOrBefore_argsTupleScheme(); - } - } - - private static class getRowOrBefore_argsTupleScheme extends TupleScheme { - - @Override - public void write(org.apache.thrift.protocol.TProtocol prot, getRowOrBefore_args struct) throws org.apache.thrift.TException { - TTupleProtocol oprot = (TTupleProtocol) prot; - BitSet optionals = new BitSet(); - if (struct.isSetTableName()) { - optionals.set(0); - } - if (struct.isSetRow()) { - optionals.set(1); - } - if (struct.isSetFamily()) { - optionals.set(2); - } - oprot.writeBitSet(optionals, 3); - if (struct.isSetTableName()) { - oprot.writeBinary(struct.tableName); - } - if (struct.isSetRow()) { - oprot.writeBinary(struct.row); - } - if (struct.isSetFamily()) { - oprot.writeBinary(struct.family); - } - } - - @Override - public void read(org.apache.thrift.protocol.TProtocol prot, getRowOrBefore_args struct) throws org.apache.thrift.TException { - TTupleProtocol iprot = (TTupleProtocol) prot; - BitSet incoming = iprot.readBitSet(3); - if (incoming.get(0)) { - struct.tableName = iprot.readBinary(); - struct.setTableNameIsSet(true); - } - if (incoming.get(1)) { - struct.row = iprot.readBinary(); - struct.setRowIsSet(true); - } - if (incoming.get(2)) { - struct.family = iprot.readBinary(); - struct.setFamilyIsSet(true); - } - } - } - - } - - public static class getRowOrBefore_result implements org.apache.thrift.TBase, java.io.Serializable, Cloneable { - private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getRowOrBefore_result"); - - private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.LIST, (short)0); - private static final org.apache.thrift.protocol.TField IO_FIELD_DESC = new org.apache.thrift.protocol.TField("io", org.apache.thrift.protocol.TType.STRUCT, (short)1); - - private static final Map, SchemeFactory> schemes = new HashMap, SchemeFactory>(); - static { - schemes.put(StandardScheme.class, new getRowOrBefore_resultStandardSchemeFactory()); - schemes.put(TupleScheme.class, new getRowOrBefore_resultTupleSchemeFactory()); - } - - public List success; // required - public IOError io; // required - - /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */ - public enum _Fields implements org.apache.thrift.TFieldIdEnum { - SUCCESS((short)0, "success"), - IO((short)1, "io"); - - private static final Map byName = new HashMap(); - - static { - for (_Fields field : EnumSet.allOf(_Fields.class)) { - byName.put(field.getFieldName(), field); - } - } - - /** - * Find the _Fields constant that matches fieldId, or null if its not found. - */ - public static _Fields findByThriftId(int fieldId) { - switch(fieldId) { - case 0: // SUCCESS - return SUCCESS; - case 1: // IO - return IO; - default: - return null; - } - } - - /** - * Find the _Fields constant that matches fieldId, throwing an exception - * if it is not found. - */ - public static _Fields findByThriftIdOrThrow(int fieldId) { - _Fields fields = findByThriftId(fieldId); - if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!"); - return fields; - } - - /** - * Find the _Fields constant that matches name, or null if its not found. - */ - public static _Fields findByName(String name) { - return byName.get(name); - } - - private final short _thriftId; - private final String _fieldName; - - _Fields(short thriftId, String fieldName) { - _thriftId = thriftId; - _fieldName = fieldName; - } - - public short getThriftFieldId() { - return _thriftId; - } - - public String getFieldName() { - return _fieldName; - } - } - - // isset id assignments - public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap; - static { - Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class); - tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, - new org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST, - new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, TCell.class)))); - tmpMap.put(_Fields.IO, new org.apache.thrift.meta_data.FieldMetaData("io", org.apache.thrift.TFieldRequirementType.DEFAULT, - new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT))); - metaDataMap = Collections.unmodifiableMap(tmpMap); - org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getRowOrBefore_result.class, metaDataMap); - } - - public getRowOrBefore_result() { - } - - public getRowOrBefore_result( - List success, - IOError io) - { - this(); - this.success = success; - this.io = io; - } - - /** - * Performs a deep copy on other. - */ - public getRowOrBefore_result(getRowOrBefore_result other) { - if (other.isSetSuccess()) { - List __this__success = new ArrayList(); - for (TCell other_element : other.success) { - __this__success.add(new TCell(other_element)); - } - this.success = __this__success; - } - if (other.isSetIo()) { - this.io = new IOError(other.io); - } - } - - public getRowOrBefore_result deepCopy() { - return new getRowOrBefore_result(this); - } - - @Override - public void clear() { - this.success = null; - this.io = null; - } - - public int getSuccessSize() { - return (this.success == null) ? 0 : this.success.size(); - } - - public java.util.Iterator getSuccessIterator() { - return (this.success == null) ? null : this.success.iterator(); - } - - public void addToSuccess(TCell elem) { - if (this.success == null) { - this.success = new ArrayList(); - } - this.success.add(elem); - } - - public List getSuccess() { - return this.success; - } - - public getRowOrBefore_result setSuccess(List success) { - this.success = success; - return this; - } - - public void unsetSuccess() { - this.success = null; - } - - /** Returns true if field success is set (has been assigned a value) and false otherwise */ - public boolean isSetSuccess() { - return this.success != null; - } - - public void setSuccessIsSet(boolean value) { - if (!value) { - this.success = null; - } - } - - public IOError getIo() { - return this.io; - } - - public getRowOrBefore_result setIo(IOError io) { - this.io = io; - return this; - } - - public void unsetIo() { - this.io = null; - } - - /** Returns true if field io is set (has been assigned a value) and false otherwise */ - public boolean isSetIo() { - return this.io != null; - } - - public void setIoIsSet(boolean value) { - if (!value) { - this.io = null; - } - } - - public void setFieldValue(_Fields field, Object value) { - switch (field) { - case SUCCESS: - if (value == null) { - unsetSuccess(); - } else { - setSuccess((List)value); - } - break; - - case IO: - if (value == null) { - unsetIo(); - } else { - setIo((IOError)value); - } - break; - - } - } - - public Object getFieldValue(_Fields field) { - switch (field) { - case SUCCESS: - return getSuccess(); - - case IO: - return getIo(); - - } - throw new IllegalStateException(); - } - - /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */ - public boolean isSet(_Fields field) { - if (field == null) { - throw new IllegalArgumentException(); - } - - switch (field) { - case SUCCESS: - return isSetSuccess(); - case IO: - return isSetIo(); - } - throw new IllegalStateException(); - } - - @Override - public boolean equals(Object that) { - if (that == null) - return false; - if (that instanceof getRowOrBefore_result) - return this.equals((getRowOrBefore_result)that); - return false; - } - - public boolean equals(getRowOrBefore_result that) { - if (that == null) - return false; - - boolean this_present_success = true && this.isSetSuccess(); - boolean that_present_success = true && that.isSetSuccess(); - if (this_present_success || that_present_success) { - if (!(this_present_success && that_present_success)) - return false; - if (!this.success.equals(that.success)) - return false; - } - - boolean this_present_io = true && this.isSetIo(); - boolean that_present_io = true && that.isSetIo(); - if (this_present_io || that_present_io) { - if (!(this_present_io && that_present_io)) - return false; - if (!this.io.equals(that.io)) - return false; - } - - return true; - } - - @Override - public int hashCode() { - return 0; - } - - public int compareTo(getRowOrBefore_result other) { - if (!getClass().equals(other.getClass())) { - return getClass().getName().compareTo(other.getClass().getName()); - } - - int lastComparison = 0; - getRowOrBefore_result typedOther = (getRowOrBefore_result)other; - - lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(typedOther.isSetSuccess()); - if (lastComparison != 0) { - return lastComparison; - } - if (isSetSuccess()) { - lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, typedOther.success); - if (lastComparison != 0) { - return lastComparison; - } - } - lastComparison = Boolean.valueOf(isSetIo()).compareTo(typedOther.isSetIo()); - if (lastComparison != 0) { - return lastComparison; - } - if (isSetIo()) { - lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.io, typedOther.io); - if (lastComparison != 0) { - return lastComparison; - } - } - return 0; - } - - public _Fields fieldForId(int fieldId) { - return _Fields.findByThriftId(fieldId); - } - - public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException { - schemes.get(iprot.getScheme()).getScheme().read(iprot, this); - } - - public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException { - schemes.get(oprot.getScheme()).getScheme().write(oprot, this); - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder("getRowOrBefore_result("); - boolean first = true; - - sb.append("success:"); - if (this.success == null) { - sb.append("null"); - } else { - sb.append(this.success); - } - first = false; - if (!first) sb.append(", "); - sb.append("io:"); - if (this.io == null) { - sb.append("null"); - } else { - sb.append(this.io); - } - first = false; - sb.append(")"); - return sb.toString(); - } - - public void validate() throws org.apache.thrift.TException { - // check for required fields - } - - private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException { - try { - write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out))); - } catch (org.apache.thrift.TException te) { - throw new java.io.IOException(te); - } - } - - private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException { - try { - read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in))); - } catch (org.apache.thrift.TException te) { - throw new java.io.IOException(te); - } - } - - private static class getRowOrBefore_resultStandardSchemeFactory implements SchemeFactory { - public getRowOrBefore_resultStandardScheme getScheme() { - return new getRowOrBefore_resultStandardScheme(); - } - } - - private static class getRowOrBefore_resultStandardScheme extends StandardScheme { - - public void read(org.apache.thrift.protocol.TProtocol iprot, getRowOrBefore_result struct) throws org.apache.thrift.TException { - org.apache.thrift.protocol.TField schemeField; - iprot.readStructBegin(); - while (true) - { - schemeField = iprot.readFieldBegin(); - if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { - break; - } - switch (schemeField.id) { - case 0: // SUCCESS - if (schemeField.type == org.apache.thrift.protocol.TType.LIST) { - { - org.apache.thrift.protocol.TList _list550 = iprot.readListBegin(); - struct.success = new ArrayList(_list550.size); - for (int _i551 = 0; _i551 < _list550.size; ++_i551) - { - TCell _elem552; // optional - _elem552 = new TCell(); - _elem552.read(iprot); - struct.success.add(_elem552); - } - iprot.readListEnd(); - } - struct.setSuccessIsSet(true); - } else { - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - break; - case 1: // IO - if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) { - struct.io = new IOError(); - struct.io.read(iprot); - struct.setIoIsSet(true); - } else { - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - break; - default: - org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); - } - iprot.readFieldEnd(); - } - iprot.readStructEnd(); - - // check for required fields of primitive type, which can't be checked in the validate method - struct.validate(); - } - - public void write(org.apache.thrift.protocol.TProtocol oprot, getRowOrBefore_result struct) throws org.apache.thrift.TException { - struct.validate(); - - oprot.writeStructBegin(STRUCT_DESC); - if (struct.success != null) { - oprot.writeFieldBegin(SUCCESS_FIELD_DESC); - { - oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, struct.success.size())); - for (TCell _iter553 : struct.success) - { - _iter553.write(oprot); - } - oprot.writeListEnd(); - } - oprot.writeFieldEnd(); - } - if (struct.io != null) { - oprot.writeFieldBegin(IO_FIELD_DESC); - struct.io.write(oprot); - oprot.writeFieldEnd(); - } - oprot.writeFieldStop(); - oprot.writeStructEnd(); - } - - } - - private static class getRowOrBefore_resultTupleSchemeFactory implements SchemeFactory { - public getRowOrBefore_resultTupleScheme getScheme() { - return new getRowOrBefore_resultTupleScheme(); - } - } - - private static class getRowOrBefore_resultTupleScheme extends TupleScheme { - - @Override - public void write(org.apache.thrift.protocol.TProtocol prot, getRowOrBefore_result struct) throws org.apache.thrift.TException { - TTupleProtocol oprot = (TTupleProtocol) prot; - BitSet optionals = new BitSet(); - if (struct.isSetSuccess()) { - optionals.set(0); - } - if (struct.isSetIo()) { - optionals.set(1); - } - oprot.writeBitSet(optionals, 2); - if (struct.isSetSuccess()) { - { - oprot.writeI32(struct.success.size()); - for (TCell _iter554 : struct.success) - { - _iter554.write(oprot); - } - } - } - if (struct.isSetIo()) { - struct.io.write(oprot); - } - } - - @Override - public void read(org.apache.thrift.protocol.TProtocol prot, getRowOrBefore_result struct) throws org.apache.thrift.TException { - TTupleProtocol iprot = (TTupleProtocol) prot; - BitSet incoming = iprot.readBitSet(2); - if (incoming.get(0)) { - { - org.apache.thrift.protocol.TList _list555 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32()); - struct.success = new ArrayList(_list555.size); - for (int _i556 = 0; _i556 < _list555.size; ++_i556) - { - TCell _elem557; // optional - _elem557 = new TCell(); - _elem557.read(iprot); - struct.success.add(_elem557); - } - } - struct.setSuccessIsSet(true); - } - if (incoming.get(1)) { - struct.io = new IOError(); - struct.io.read(iprot); - struct.setIoIsSet(true); - } - } - } - - } - - public static class getRegionInfo_args implements org.apache.thrift.TBase, java.io.Serializable, Cloneable { - private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getRegionInfo_args"); - - private static final org.apache.thrift.protocol.TField ROW_FIELD_DESC = new org.apache.thrift.protocol.TField("row", org.apache.thrift.protocol.TType.STRING, (short)1); - - private static final Map, SchemeFactory> schemes = new HashMap, SchemeFactory>(); - static { - schemes.put(StandardScheme.class, new getRegionInfo_argsStandardSchemeFactory()); - schemes.put(TupleScheme.class, new getRegionInfo_argsTupleSchemeFactory()); - } - - /** - * row key - */ - public ByteBuffer row; // required - - /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */ - public enum _Fields implements org.apache.thrift.TFieldIdEnum { - /** - * row key - */ - ROW((short)1, "row"); - - private static final Map byName = new HashMap(); - - static { - for (_Fields field : EnumSet.allOf(_Fields.class)) { - byName.put(field.getFieldName(), field); - } - } - - /** - * Find the _Fields constant that matches fieldId, or null if its not found. - */ - public static _Fields findByThriftId(int fieldId) { - switch(fieldId) { - case 1: // ROW - return ROW; - default: - return null; - } - } - - /** - * Find the _Fields constant that matches fieldId, throwing an exception - * if it is not found. - */ - public static _Fields findByThriftIdOrThrow(int fieldId) { - _Fields fields = findByThriftId(fieldId); - if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!"); - return fields; - } - - /** - * Find the _Fields constant that matches name, or null if its not found. - */ - public static _Fields findByName(String name) { - return byName.get(name); - } - - private final short _thriftId; - private final String _fieldName; - - _Fields(short thriftId, String fieldName) { - _thriftId = thriftId; - _fieldName = fieldName; - } - - public short getThriftFieldId() { - return _thriftId; - } - - public String getFieldName() { - return _fieldName; - } - } - - // isset id assignments - public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap; - static { - Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class); - tmpMap.put(_Fields.ROW, new org.apache.thrift.meta_data.FieldMetaData("row", org.apache.thrift.TFieldRequirementType.DEFAULT, - new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING , "Text"))); - metaDataMap = Collections.unmodifiableMap(tmpMap); - org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getRegionInfo_args.class, metaDataMap); - } - - public getRegionInfo_args() { - } - - public getRegionInfo_args( - ByteBuffer row) - { - this(); - this.row = row; - } - - /** - * Performs a deep copy on other. - */ - public getRegionInfo_args(getRegionInfo_args other) { - if (other.isSetRow()) { - this.row = other.row; - } - } - - public getRegionInfo_args deepCopy() { - return new getRegionInfo_args(this); - } - - @Override - public void clear() { - this.row = null; - } - - /** - * row key - */ - public byte[] getRow() { - setRow(org.apache.thrift.TBaseHelper.rightSize(row)); - return row == null ? null : row.array(); - } - - public ByteBuffer bufferForRow() { - return row; - } - - /** - * row key - */ - public getRegionInfo_args setRow(byte[] row) { - setRow(row == null ? (ByteBuffer)null : ByteBuffer.wrap(row)); - return this; - } - - public getRegionInfo_args setRow(ByteBuffer row) { - this.row = row; - return this; - } - - public void unsetRow() { - this.row = null; - } - - /** Returns true if field row is set (has been assigned a value) and false otherwise */ - public boolean isSetRow() { - return this.row != null; - } - - public void setRowIsSet(boolean value) { - if (!value) { - this.row = null; - } - } - - public void setFieldValue(_Fields field, Object value) { - switch (field) { - case ROW: - if (value == null) { - unsetRow(); - } else { - setRow((ByteBuffer)value); - } - break; - - } - } - - public Object getFieldValue(_Fields field) { - switch (field) { - case ROW: - return getRow(); - - } - throw new IllegalStateException(); - } - - /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */ - public boolean isSet(_Fields field) { - if (field == null) { - throw new IllegalArgumentException(); - } - - switch (field) { - case ROW: - return isSetRow(); - } - throw new IllegalStateException(); - } - - @Override - public boolean equals(Object that) { - if (that == null) - return false; - if (that instanceof getRegionInfo_args) - return this.equals((getRegionInfo_args)that); - return false; - } - - public boolean equals(getRegionInfo_args that) { - if (that == null) - return false; - - boolean this_present_row = true && this.isSetRow(); - boolean that_present_row = true && that.isSetRow(); - if (this_present_row || that_present_row) { - if (!(this_present_row && that_present_row)) - return false; - if (!this.row.equals(that.row)) - return false; - } - - return true; - } - - @Override - public int hashCode() { - return 0; - } - - public int compareTo(getRegionInfo_args other) { - if (!getClass().equals(other.getClass())) { - return getClass().getName().compareTo(other.getClass().getName()); - } - - int lastComparison = 0; - getRegionInfo_args typedOther = (getRegionInfo_args)other; - - lastComparison = Boolean.valueOf(isSetRow()).compareTo(typedOther.isSetRow()); - if (lastComparison != 0) { - return lastComparison; - } - if (isSetRow()) { - lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.row, typedOther.row); - if (lastComparison != 0) { - return lastComparison; - } - } - return 0; - } - - public _Fields fieldForId(int fieldId) { - return _Fields.findByThriftId(fieldId); - } - - public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException { - schemes.get(iprot.getScheme()).getScheme().read(iprot, this); - } - - public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException { - schemes.get(oprot.getScheme()).getScheme().write(oprot, this); - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder("getRegionInfo_args("); + StringBuilder sb = new StringBuilder("getRegionInfo_args("); boolean first = true; sb.append("row:"); @@ -51079,7 +51014,19 @@ public class Hbase { @Override public int hashCode() { - return 0; + HashCodeBuilder builder = new HashCodeBuilder(); + + boolean present_success = true && (isSetSuccess()); + builder.append(present_success); + if (present_success) + builder.append(success); + + boolean present_io = true && (isSetIo()); + builder.append(present_io); + if (present_io) + builder.append(io); + + return builder.toHashCode(); } public int compareTo(getRegionInfo_result other) { diff --git src/main/java/org/apache/hadoop/hbase/thrift/generated/IOError.java src/main/java/org/apache/hadoop/hbase/thrift/generated/IOError.java index 11e31e3..08ba49e 100644 --- src/main/java/org/apache/hadoop/hbase/thrift/generated/IOError.java +++ src/main/java/org/apache/hadoop/hbase/thrift/generated/IOError.java @@ -6,6 +6,7 @@ */ package org.apache.hadoop.hbase.thrift.generated; +import org.apache.commons.lang.builder.HashCodeBuilder; import org.apache.thrift.scheme.IScheme; import org.apache.thrift.scheme.SchemeFactory; import org.apache.thrift.scheme.StandardScheme; @@ -227,7 +228,14 @@ public class IOError extends Exception implements org.apache.thrift.TBase, jav @Override public int hashCode() { - return 0; + HashCodeBuilder builder = new HashCodeBuilder(); + + boolean present_value = true && (isSetValue()); + builder.append(present_value); + if (present_value) + builder.append(value); + + boolean present_timestamp = true; + builder.append(present_timestamp); + if (present_timestamp) + builder.append(timestamp); + + return builder.toHashCode(); } public int compareTo(TCell other) { diff --git src/main/java/org/apache/hadoop/hbase/thrift/generated/TRegionInfo.java src/main/java/org/apache/hadoop/hbase/thrift/generated/TRegionInfo.java index ed251e8..d23cc70 100644 --- src/main/java/org/apache/hadoop/hbase/thrift/generated/TRegionInfo.java +++ src/main/java/org/apache/hadoop/hbase/thrift/generated/TRegionInfo.java @@ -6,6 +6,7 @@ */ package org.apache.hadoop.hbase.thrift.generated; +import org.apache.commons.lang.builder.HashCodeBuilder; import org.apache.thrift.scheme.IScheme; import org.apache.thrift.scheme.SchemeFactory; import org.apache.thrift.scheme.StandardScheme; @@ -622,7 +623,44 @@ public class TRegionInfo implements org.apache.thrift.TBase, jav @Override public int hashCode() { - return 0; + HashCodeBuilder builder = new HashCodeBuilder(); + + boolean present_startRow = true && (isSetStartRow()); + builder.append(present_startRow); + if (present_startRow) + builder.append(startRow); + + boolean present_stopRow = true && (isSetStopRow()); + builder.append(present_stopRow); + if (present_stopRow) + builder.append(stopRow); + + boolean present_timestamp = true && (isSetTimestamp()); + builder.append(present_timestamp); + if (present_timestamp) + builder.append(timestamp); + + boolean present_columns = true && (isSetColumns()); + builder.append(present_columns); + if (present_columns) + builder.append(columns); + + boolean present_caching = true && (isSetCaching()); + builder.append(present_caching); + if (present_caching) + builder.append(caching); + + boolean present_filterString = true && (isSetFilterString()); + builder.append(present_filterString); + if (present_filterString) + builder.append(filterString); + + return builder.toHashCode(); } public int compareTo(TScan other) { @@ -772,7 +805,7 @@ public class TScan implements org.apache.thrift.TBase, jav struct.columns = new ArrayList(_list18.size); for (int _i19 = 0; _i19 < _list18.size; ++_i19) { - ByteBuffer _elem20; // optional + ByteBuffer _elem20; // required _elem20 = iprot.readBinary(); struct.columns.add(_elem20); } @@ -944,7 +977,7 @@ public class TScan implements org.apache.thrift.TBase, jav struct.columns = new ArrayList(_list23.size); for (int _i24 = 0; _i24 < _list23.size; ++_i24) { - ByteBuffer _elem25; // optional + ByteBuffer _elem25; // required _elem25 = iprot.readBinary(); struct.columns.add(_elem25); } diff --git src/main/java/org/apache/hadoop/hbase/util/FSUtils.java src/main/java/org/apache/hadoop/hbase/util/FSUtils.java index aebe5b0..bc6fc94 100644 --- src/main/java/org/apache/hadoop/hbase/util/FSUtils.java +++ src/main/java/org/apache/hadoop/hbase/util/FSUtils.java @@ -308,7 +308,7 @@ public abstract class FSUtils { FSUtils.setVersion(fs, rootdir, wait, retries); return; } - } else if (version.compareTo(HConstants.FILE_SYSTEM_VERSION) == 0) + } else if (version.compareTo(HConstants.FILE_SYSTEM_VERSION) <= 0) return; // version is deprecated require migration diff --git src/main/java/org/apache/hadoop/hbase/util/RetryCounter.java src/main/java/org/apache/hadoop/hbase/util/RetryCounter.java index dee5301..0d1c5ea 100644 --- src/main/java/org/apache/hadoop/hbase/util/RetryCounter.java +++ src/main/java/org/apache/hadoop/hbase/util/RetryCounter.java @@ -52,7 +52,8 @@ public class RetryCounter { public void sleepUntilNextRetry() throws InterruptedException { int attempts = getAttemptTimes(); long sleepTime = (long) (retryIntervalMillis * Math.pow(2, attempts)); - LOG.info("Sleeping " + sleepTime + "ms before retry #" + attempts + "..."); + LOG.info("The " + attempts + " times to retry after sleeping " + sleepTime + + " ms"); timeUnit.sleep(sleepTime); } @@ -67,4 +68,4 @@ public class RetryCounter { public int getAttemptTimes() { return maxRetries-retriesRemaining+1; } -} +} \ No newline at end of file diff --git src/main/java/org/apache/hadoop/hbase/util/Writables.java src/main/java/org/apache/hadoop/hbase/util/Writables.java index 3d20723..ce9d598 100644 --- src/main/java/org/apache/hadoop/hbase/util/Writables.java +++ src/main/java/org/apache/hadoop/hbase/util/Writables.java @@ -22,6 +22,7 @@ package org.apache.hadoop.hbase.util; import org.apache.hadoop.classification.InterfaceAudience; import org.apache.hadoop.hbase.HRegionInfo; import org.apache.hadoop.hbase.migration.HRegionInfo090x; +import org.apache.hadoop.hbase.migration.HRegionInfo090x2; import org.apache.hadoop.io.DataInputBuffer; import org.apache.hadoop.io.Writable; @@ -151,6 +152,17 @@ public class Writables { /** * @param bytes serialized bytes + * @return A HRegionInfo instance built out of passed bytes. + * @throws IOException e + */ + public static HRegionInfo090x2 getHRegionInfo90x2(final byte [] bytes) + throws IOException { + return (HRegionInfo090x2)getWritable(bytes, new HRegionInfo090x2()); + } + + + /** + * @param bytes serialized bytes * @return All the hregioninfos that are in the byte array. Keeps reading * till we hit the end. * @throws IOException e diff --git src/main/java/org/apache/hadoop/hbase/zookeeper/RecoverableZooKeeper.java src/main/java/org/apache/hadoop/hbase/zookeeper/RecoverableZooKeeper.java index 233c3cc..a484d36 100644 --- src/main/java/org/apache/hadoop/hbase/zookeeper/RecoverableZooKeeper.java +++ src/main/java/org/apache/hadoop/hbase/zookeeper/RecoverableZooKeeper.java @@ -77,18 +77,10 @@ public class RecoverableZooKeeper { private int sessionTimeout; private String quorumServers; - // The metadata attached to each piece of data has the - // format: - // 1-byte constant - // 4-byte big-endian integer (length of next field) - // identifier corresponding uniquely to this process - // It is prepended to the data supplied by the user. - + private static final int ID_OFFSET = Bytes.SIZEOF_INT; // the magic number is to be backward compatible private static final byte MAGIC =(byte) 0XFF; - private static final int MAGIC_SIZE = Bytes.SIZEOF_BYTE; - private static final int ID_LENGTH_OFFSET = MAGIC_SIZE; - private static final int ID_LENGTH_SIZE = Bytes.SIZEOF_INT; + private static final int MAGIC_OFFSET = Bytes.SIZEOF_BYTE; public RecoverableZooKeeper(String quorumServers, int sessionTimeout, Watcher watcher, int maxRetries, int retryIntervalMillis) @@ -119,9 +111,12 @@ public class RecoverableZooKeeper { } /** - * delete is an idempotent operation. Retry before throwing exception. - * This function will not throw NoNodeException if the path does not - * exist. + * delete is an idempotent operation. Retry before throw out exception. + * This function will not throw out NoNodeException if the path is not existed + * @param path + * @param version + * @throws InterruptedException + * @throws KeeperException */ public void delete(String path, int version) throws InterruptedException, KeeperException { @@ -146,7 +141,12 @@ public class RecoverableZooKeeper { case CONNECTIONLOSS: case SESSIONEXPIRED: case OPERATIONTIMEOUT: - retryOrThrow(retryCounter, e, "delete"); + LOG.warn("Possibly transient ZooKeeper exception: " + e); + if (!retryCounter.shouldRetry()) { + LOG.error("ZooKeeper delete failed after " + + retryCounter.getMaxRetries() + " retries"); + throw e; + } break; default: @@ -160,8 +160,12 @@ public class RecoverableZooKeeper { } /** - * exists is an idempotent operation. Retry before throwing exception + * exists is an idempotent operation. Retry before throw out exception + * @param path + * @param watcher * @return A Stat instance + * @throws KeeperException + * @throws InterruptedException */ public Stat exists(String path, Watcher watcher) throws KeeperException, InterruptedException { @@ -174,7 +178,12 @@ public class RecoverableZooKeeper { case CONNECTIONLOSS: case SESSIONEXPIRED: case OPERATIONTIMEOUT: - retryOrThrow(retryCounter, e, "exists"); + LOG.warn("Possibly transient ZooKeeper exception: " + e); + if (!retryCounter.shouldRetry()) { + LOG.error("ZooKeeper exists failed after " + + retryCounter.getMaxRetries() + " retries"); + throw e; + } break; default: @@ -187,8 +196,12 @@ public class RecoverableZooKeeper { } /** - * exists is an idempotent operation. Retry before throwing exception + * exists is an idempotent operation. Retry before throw out exception + * @param path + * @param watch * @return A Stat instance + * @throws KeeperException + * @throws InterruptedException */ public Stat exists(String path, boolean watch) throws KeeperException, InterruptedException { @@ -201,7 +214,12 @@ public class RecoverableZooKeeper { case CONNECTIONLOSS: case SESSIONEXPIRED: case OPERATIONTIMEOUT: - retryOrThrow(retryCounter, e, "exists"); + LOG.warn("Possibly transient ZooKeeper exception: " + e); + if (!retryCounter.shouldRetry()) { + LOG.error("ZooKeeper exists failed after " + + retryCounter.getMaxRetries() + " retries"); + throw e; + } break; default: @@ -213,19 +231,13 @@ public class RecoverableZooKeeper { } } - private void retryOrThrow(RetryCounter retryCounter, KeeperException e, - String opName) throws KeeperException { - LOG.warn("Possibly transient ZooKeeper exception: " + e); - if (!retryCounter.shouldRetry()) { - LOG.error("ZooKeeper " + opName + " failed after " - + retryCounter.getMaxRetries() + " retries"); - throw e; - } - } - /** - * getChildren is an idempotent operation. Retry before throwing exception + * getChildren is an idempotent operation. Retry before throw out exception + * @param path + * @param watcher * @return List of children znodes + * @throws KeeperException + * @throws InterruptedException */ public List getChildren(String path, Watcher watcher) throws KeeperException, InterruptedException { @@ -238,7 +250,12 @@ public class RecoverableZooKeeper { case CONNECTIONLOSS: case SESSIONEXPIRED: case OPERATIONTIMEOUT: - retryOrThrow(retryCounter, e, "getChildren"); + LOG.warn("Possibly transient ZooKeeper exception: " + e); + if (!retryCounter.shouldRetry()) { + LOG.error("ZooKeeper getChildren failed after " + + retryCounter.getMaxRetries() + " retries"); + throw e; + } break; default: @@ -251,8 +268,12 @@ public class RecoverableZooKeeper { } /** - * getChildren is an idempotent operation. Retry before throwing exception + * getChildren is an idempotent operation. Retry before throw out exception + * @param path + * @param watch * @return List of children znodes + * @throws KeeperException + * @throws InterruptedException */ public List getChildren(String path, boolean watch) throws KeeperException, InterruptedException { @@ -265,7 +286,12 @@ public class RecoverableZooKeeper { case CONNECTIONLOSS: case SESSIONEXPIRED: case OPERATIONTIMEOUT: - retryOrThrow(retryCounter, e, "getChildren"); + LOG.warn("Possibly transient ZooKeeper exception: " + e); + if (!retryCounter.shouldRetry()) { + LOG.error("ZooKeeper getChildren failed after " + + retryCounter.getMaxRetries() + " retries"); + throw e; + } break; default: @@ -278,8 +304,13 @@ public class RecoverableZooKeeper { } /** - * getData is an idempotent operation. Retry before throwing exception + * getData is an idempotent operation. Retry before throw out exception + * @param path + * @param watcher + * @param stat * @return Data + * @throws KeeperException + * @throws InterruptedException */ public byte[] getData(String path, Watcher watcher, Stat stat) throws KeeperException, InterruptedException { @@ -293,7 +324,12 @@ public class RecoverableZooKeeper { case CONNECTIONLOSS: case SESSIONEXPIRED: case OPERATIONTIMEOUT: - retryOrThrow(retryCounter, e, "getData"); + LOG.warn("Possibly transient ZooKeeper exception: " + e); + if (!retryCounter.shouldRetry()) { + LOG.error("ZooKeeper getData failed after " + + retryCounter.getMaxRetries() + " retries"); + throw e; + } break; default: @@ -306,8 +342,13 @@ public class RecoverableZooKeeper { } /** - * getData is an idemnpotent operation. Retry before throwing exception + * getData is an idemnpotent operation. Retry before throw out exception + * @param path + * @param watch + * @param stat * @return Data + * @throws KeeperException + * @throws InterruptedException */ public byte[] getData(String path, boolean watch, Stat stat) throws KeeperException, InterruptedException { @@ -321,7 +362,12 @@ public class RecoverableZooKeeper { case CONNECTIONLOSS: case SESSIONEXPIRED: case OPERATIONTIMEOUT: - retryOrThrow(retryCounter, e, "getData"); + LOG.warn("Possibly transient ZooKeeper exception: " + e); + if (!retryCounter.shouldRetry()) { + LOG.error("ZooKeeper getData failed after " + + retryCounter.getMaxRetries() + " retries"); + throw e; + } break; default: @@ -337,7 +383,12 @@ public class RecoverableZooKeeper { * setData is NOT an idempotent operation. Retry may cause BadVersion Exception * Adding an identifier field into the data to check whether * badversion is caused by the result of previous correctly setData + * @param path + * @param data + * @param version * @return Stat instance + * @throws KeeperException + * @throws InterruptedException */ public Stat setData(String path, byte[] data, int version) throws KeeperException, InterruptedException { @@ -351,28 +402,33 @@ public class RecoverableZooKeeper { case CONNECTIONLOSS: case SESSIONEXPIRED: case OPERATIONTIMEOUT: - retryOrThrow(retryCounter, e, "setData"); + LOG.warn("Possibly transient ZooKeeper exception: " + e); + if (!retryCounter.shouldRetry()) { + LOG.error("ZooKeeper setData failed after " + + retryCounter.getMaxRetries() + " retries"); + throw e; + } break; case BADVERSION: // try to verify whether the previous setData success or not try{ Stat stat = new Stat(); byte[] revData = zk.getData(path, false, stat); - int idLength = Bytes.toInt(revData, ID_LENGTH_SIZE); - int dataLength = revData.length-ID_LENGTH_SIZE-idLength; - int dataOffset = ID_LENGTH_SIZE+idLength; + int idLength = Bytes.toInt(revData, ID_OFFSET); + int dataLength = revData.length-ID_OFFSET-idLength; + int dataOffset = ID_OFFSET+idLength; - if(Bytes.compareTo(revData, ID_LENGTH_SIZE, id.length, + if(Bytes.compareTo(revData, ID_OFFSET, id.length, revData, dataOffset, dataLength) == 0) { // the bad version is caused by previous successful setData return stat; } } catch(KeeperException keeperException){ - // the ZK is not reliable at this moment. just throwing exception + // the ZK is not reliable at this moment. just throw out exception throw keeperException; } - // throw other exceptions and verified bad version exceptions + // throw out other exceptions and verified bad version exceptions default: throw e; } @@ -385,8 +441,8 @@ public class RecoverableZooKeeper { /** *

* NONSEQUENTIAL create is idempotent operation. - * Retry before throwing exceptions. - * But this function will not throw the NodeExist exception back to the + * Retry before throw out exceptions. + * But this function will not throw out the NodeExist exception back to the * application. *

*

@@ -395,7 +451,13 @@ public class RecoverableZooKeeper { * or not. *

* + * @param path + * @param data + * @param acl + * @param createMode * @return Path + * @throws KeeperException + * @throws InterruptedException */ public String create(String path, byte[] data, List acl, CreateMode createMode) @@ -448,7 +510,12 @@ public class RecoverableZooKeeper { case CONNECTIONLOSS: case SESSIONEXPIRED: case OPERATIONTIMEOUT: - retryOrThrow(retryCounter, e, "create"); + LOG.warn("Possibly transient ZooKeeper exception: " + e); + if (!retryCounter.shouldRetry()) { + LOG.error("ZooKeeper create failed after " + + retryCounter.getMaxRetries() + " retries"); + throw e; + } break; default: @@ -483,7 +550,12 @@ public class RecoverableZooKeeper { case CONNECTIONLOSS: case SESSIONEXPIRED: case OPERATIONTIMEOUT: - retryOrThrow(retryCounter, e, "create"); + LOG.warn("Possibly transient ZooKeeper exception: " + e); + if (!retryCounter.shouldRetry()) { + LOG.error("ZooKeeper create failed after " + + retryCounter.getMaxRetries() + " retries"); + throw e; + } break; default: @@ -524,9 +596,9 @@ public class RecoverableZooKeeper { return data; } - int idLength = Bytes.toInt(data, ID_LENGTH_OFFSET); - int dataLength = data.length-MAGIC_SIZE-ID_LENGTH_SIZE-idLength; - int dataOffset = MAGIC_SIZE+ID_LENGTH_SIZE+idLength; + int idLength = Bytes.toInt(data, MAGIC_OFFSET); + int dataLength = data.length-MAGIC_OFFSET-ID_OFFSET-idLength; + int dataOffset = MAGIC_OFFSET+ID_OFFSET+idLength; byte[] newData = new byte[dataLength]; System.arraycopy(data, dataOffset, newData, 0, dataLength); @@ -540,7 +612,7 @@ public class RecoverableZooKeeper { return data; } - byte[] newData = new byte[MAGIC_SIZE+ID_LENGTH_SIZE+id.length+data.length]; + byte[] newData = new byte[MAGIC_OFFSET+ID_OFFSET+id.length+data.length]; int pos = 0; pos = Bytes.putByte(newData, pos, MAGIC); pos = Bytes.putInt(newData, pos, id.length); diff --git src/main/java/org/apache/hadoop/hbase/zookeeper/ZKConfig.java src/main/java/org/apache/hadoop/hbase/zookeeper/ZKConfig.java index b6fef32..cb1539e 100644 --- src/main/java/org/apache/hadoop/hbase/zookeeper/ZKConfig.java +++ src/main/java/org/apache/hadoop/hbase/zookeeper/ZKConfig.java @@ -163,8 +163,7 @@ public class ZKConfig { } // Special case for 'hbase.cluster.distributed' property being 'true' if (key.startsWith("server.")) { - if (conf.get(HConstants.CLUSTER_DISTRIBUTED, HConstants.DEFAULT_CLUSTER_DISTRIBUTED). - equals(HConstants.CLUSTER_IS_DISTRIBUTED) + if (conf.get(HConstants.CLUSTER_DISTRIBUTED).equals(HConstants.CLUSTER_IS_DISTRIBUTED) && value.startsWith(HConstants.LOCALHOST)) { String msg = "The server in zoo.cfg cannot be set to localhost " + "in a fully-distributed setup because it won't be reachable. " + diff --git src/main/resources/org/apache/hadoop/hbase/rest/XMLSchema.xsd src/main/resources/org/apache/hadoop/hbase/rest/XMLSchema.xsd index c2df60d..de4fff1 100644 --- src/main/resources/org/apache/hadoop/hbase/rest/XMLSchema.xsd +++ src/main/resources/org/apache/hadoop/hbase/rest/XMLSchema.xsd @@ -166,13 +166,6 @@ - - - - - - - diff --git src/main/resources/org/apache/hadoop/hbase/rest/protobuf/StorageClusterStatusMessage.proto src/main/resources/org/apache/hadoop/hbase/rest/protobuf/StorageClusterStatusMessage.proto index 46e275d..2b032f7 100644 --- src/main/resources/org/apache/hadoop/hbase/rest/protobuf/StorageClusterStatusMessage.proto +++ src/main/resources/org/apache/hadoop/hbase/rest/protobuf/StorageClusterStatusMessage.proto @@ -26,13 +26,6 @@ message StorageClusterStatus { optional int32 storefileSizeMB = 4; optional int32 memstoreSizeMB = 5; optional int32 storefileIndexSizeMB = 6; - optional int64 readRequestsCount = 7; - optional int64 writeRequestsCount = 8; - optional int32 rootIndexSizeKB = 9; - optional int32 totalStaticIndexSizeKB = 10; - optional int32 totalStaticBloomSizeKB = 11; - optional int64 totalCompactingKVs = 12; - optional int64 currentCompactedKVs = 13; } message Node { required string name = 1; // name:port diff --git src/main/resources/org/apache/hadoop/hbase/thrift/Hbase.thrift src/main/resources/org/apache/hadoop/hbase/thrift/Hbase.thrift index f698a6c..c4c783d 100644 --- src/main/resources/org/apache/hadoop/hbase/thrift/Hbase.thrift +++ src/main/resources/org/apache/hadoop/hbase/thrift/Hbase.thrift @@ -858,22 +858,6 @@ service Hbase { ) throws (1:IOError io, 2:IllegalArgument ia) /** - * Get the row just before the specified one. - * - * @return value for specified row/column - */ - list getRowOrBefore( - /** name of table */ - 1:Text tableName, - - /** row key */ - 2:Text row, - - /** column name */ - 3:Text family - ) throws (1:IOError io) - - /** * Get the regininfo for the specified row. It scans * the metatable to find region's start and end keys. * diff --git src/test/data/generate-hbase-2600-root-in-tmp.sh src/test/data/generate-hbase-2600-root-in-tmp.sh new file mode 100644 index 0000000..f886e12 --- /dev/null +++ src/test/data/generate-hbase-2600-root-in-tmp.sh @@ -0,0 +1,14 @@ +#!/bin/sh +set -ev +echo "create 't1','c1'" +NUM_PUTS=1000 +NUM_SPLITS=5 +FOO="dfjsgkljsdfklgjklsdjgkldjsfgjsdfklgjklsddfjsgkljsdfklgjklsdjgkldjsfgjsdfklgjklsddfjsgkljsdfklgjklsdjgkldjsfgjsdfklgjklsddfjsgkljsdfklgjklsdjgkldjsfgjsdfklgjklsddfjsgkljsdfklgjklsdjgkldjsfgjsdfklgjklsddfjsgkljsdfklgjklsdjgkldjsfgjsdfklgjklsddfjsgkljsdfklgjklsdjgkldjsfgjsdfklgjklsd dfjsgkljsdfklgjklsdjgkldjsfgjsdfklgjklsddfjsgkljsdfklgjklsdjgkldjsfgjsdfklgjklsddfjsgkljsdfklgjklsdjgkldjsfgjsdfklgjklsddfjsgkljsdfklgjklsdjgkldjsfgjsdfklgjklsddfjsgkljsdfklgjklsdjgkldjsfgjsdfklgjklsddfjsgkljsdfklgjklsdjgkldjsfgjsdfklgjklsddfjsgkljsdfklgjklsdjgkldjsfgjsdfklgjklsddfjsgkljsdfklgjklsdjgkldjsfgjsdfklgjklsd dfjsgkljsdfklgjklsdjgkldjsfgjsdfklgjklsddfjsgkljsdfklgjklsdjgkldjsfgjsdfklgjklsddfjsgkljsdfklgjklsdjgkldjsfgjsdfklgjklsddfjsgkljsdfklgjklsdjgkldjsfgjsdfklgjklsddfjsgkljsdfklgjklsdjgkldjsfgjsdfklgjklsddfjsgkljsdfklgjklsdjgkldjsfgjsdfklgjklsddfjsgkljsdfklgjklsdjgkldjsfgjsdfklgjklsddfjsgkljsdfklgjklsdjgkldjsfgjsdfklgjklsd dfjsgkljsdfklgjklsdjgkldjsfgjsdfklgjklsddfjsgkljsdfklgjklsdjgkldjsfgjsdfklgjklsddfjsgkljsdfklgjklsdjgkldjsfgjsdfklgjklsddfjsgkljsdfklgjklsdjgkldjsfgjsdfklgjklsddfjsgkljsdfklgjklsdjgkldjsfgjsdfklgjklsddfjsgkljsdfklgjklsdjgkldjsfgjsdfklgjklsddfjsgkljsdfklgjklsdjgkldjsfgjsdfklgjklsddfjsgkljsdfklgjklsdjgkldjsfgjsdfklgjklsd dfjsgkljsdfklgjklsdjgkldjsfgjsdfklgjklsddfjsgkljsdfklgjklsdjgkldjsfgjsdfklgjklsddfjsgkljsdfklgjklsdjgkldjsfgjsdfklgjklsddfjsgkljsdfklgjklsdjgkldjsfgjsdfklgjklsddfjsgkljsdfklgjklsdjgkldjsfgjsdfklgjklsddfjsgkljsdfklgjklsdjgkldjsfgjsdfklgjklsddfjsgkljsdfklgjklsdjgkldjsfgjsdfklgjklsddfjsgkljsdfklgjklsdjgkldjsfgjsdfklgjklsd dfjsgkljsdfklgjklsdjgkldjsfgjsdfklgjklsddfjsgkljsdfklgjklsdjgkldjsfgjsdfklgjklsddfjsgkljsdfklgjklsdjgkldjsfgjsdfklgjklsddfjsgkljsdfklgjklsdjgkldjsfgjsdfklgjklsddfjsgkljsdfklgjklsdjgkldjsfgjsdfklgjklsddfjsgkljsdfklgjklsdjgkldjsfgjsdfklgjklsddfjsgkljsdfklgjklsdjgkldjsfgjsdfklgjklsddfjsgkljsdfklgjklsdjgkldjsfgjsdfklgjklsd dfjsgkljsdfklgjklsdjgkldjsfgjsdfklgjklsddfjsgkljsdfklgjklsdjgkldjsfgjsdfklgjklsddfjsgkljsdfklgjklsdjgkldjsfgjsdfklgjklsddfjsgkljsdfklgjklsdjgkldjsfgjsdfklgjklsddfjsgkljsdfklgjklsdjgkldjsfgjsdfklgjklsddfjsgkljsdfklgjklsdjgkldjsfgjsdfklgjklsddfjsgkljsdfklgjklsdjgkldjsfgjsdfklgjklsddfjsgkljsdfklgjklsdjgkldjsfgjsdfklgjklsd dfjsgkljsdfklgjklsdjgkldjsfgjsdfklgjklsddfjsgkljsdfklgjklsdjgkldjsfgjsdfklgjklsddfjsgkljsdfklgjklsdjgkldjsfgjsdfklgjklsddfjsgkljsdfklgjklsdjgkldjsfgjsdfklgjklsddfjsgkljsdfklgjklsdjgkldjsfgjsdfklgjklsddfjsgkljsdfklgjklsdjgkldjsfgjsdfklgjklsddfjsgkljsdfklgjklsdjgkldjsfgjsdfklgjklsddfjsgkljsdfklgjklsdjgkldjsfgjsdfklgjklsd dfjsgkljsdfklgjklsdjgkldjsfgjsdfklgjklsd" +for i in `seq 1 $NUM_PUTS` + do echo "put 't1','r${i}','c1','${FOO}'" +done +for i in `seq 1 $NUM_SPLITS` + do echo "split 't1'" + echo "list" + echo scan "'.META.'" +done diff --git src/test/data/hbase-2600-root.dir.tgz src/test/data/hbase-2600-root.dir.tgz new file mode 100644 index 0000000000000000000000000000000000000000..f606141ebd1544ed17b8ca71a34eab91f5823994 GIT binary patch literal 260764 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

Ag>_r2IgBRD0p&N*hr!INY_Q5 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

=hxaR%@`Gx?q)*cN#*{am*!I@tg>irGS%>s9 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

v@(=i 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๝kR!j|9uvVJ7yOR6Q04rrz{F-eF|TEanS#3n>HG_reJy|Lq)%6K zQPRdL-MUthQjRKn__yxBgL(f)=|fe;?d5NV4pWEy)EOpI^kZb-e31f`PCXI=r`xJL zF<Nsw@4&{FmOAATC_!I?z}sSlrn@ICrh0 z2cUu3xNq09WjhMMAj`af3vULVgl#!wM1lV9fg52|HF6ygF*M|PjA?R8(Dy%gEC}Sa zRRJQ+{DezW(DDa=|LUg znSkjnH>iRr@#NXxhn3J*!Pr$ZggU@gJO2%k`>W2a+d^-YgOipqW{z53i&7OR%7oz4 zmG)ZI%=Y=SRZj;}&}QL6)u3OIr-Z$-ZY>4*BiGkz9|)eaM!0k7gGkL|(Q$U8wh;*j zDdlNUFpr<{3a~^XK6}2@t>3VL8J@v!m{^+S; zr#&`#c*G$qB6ei6AKTO4VNY6XX4+{P%YN)?7_Y#>%}@|kU= zmc*L5e4G&Gq`uCDHMqDFr_zHbjJ2%3Rbv7PbYt;0*ar!{b%AL-zee*wU|FERj$MrG z>k!S(=7Mr6b*q&Oqf5CBft45N?n3Ebc3$bhA=d+u*Se&RB6P<>Y+n}B!42gcwFEwi z(#zC=`ncHE&x~5P-rI0zPO%&7)?evLZDp}dwG=J^AVerW;C#BdejHK+WAnIH!U8_T z=pkn@vpLC-138ppl>Cg5?T(}ClS@T@&{Mkh*M_bXj*cS|@KFo!pDaoJ{jIVIZ2o!O z^~L7veMgvH}{EH$M!qOWKO$8mxCRDyc}?63A)2*Q6Y!F@-T03_yWWrHO{1{ zHjH1cc%9rCCDn(PK3XNZZS!E3w*wOk% zo;!Z>k-dKpbBz7P+nqSj>3{sa^a1?g^Yi^@_ko}52>Af<7{L64!P%bE`~Hs)0^xqM z|J8lrS3b|*Us8X>U4Pjw|LWaB$-%F99acaqdKk$`KR)#`(671gheN#x@VAe8hW{xb z<$L^R55Q`7?4Jn;41LL;_x}-j%&!6Xr~Ws+$e#y%i#+b-1EhjRACgX;NWS)b{{UtL zH~^b3fc_!Cz|7pEz$f9xFE}(n7XYaEUM2$=7$yM#YoGUkZybQn8e|+`@bkW24-wGZ z{!@N+02ukU_y8Cj`5PLW8-Jbs00c+?lb-;M4?<0>41gBEU-VaFB|k1RGdVRlI5syi zIWRXjG&wZ+$>0VYVDTkD(FSPzt%;$V0rUXAB#!&<03q}Am$4XvRd1!>l8Zd9-1@CO zw5&N-hB_VRMoA8`(GpH;e!O|VP@cEn6!ve0JAG19Q4b~jv|_uIJv!e4*W4-QP(q(WN(XB{TSE$8@?|b;(zU|R@@LOV|_P)6yjwK85qGS%x9mZGi z6|E%)=TxdM#I;oF^Ah#YaspRee@-bgtbkgDJs_4x==OEeyMm~^VrvTMyn8nOuGv-W z%XhZE^dWf;@F|=m=GlC4X-Xh;K}XKP+{?W3G6eh?x5(cf=NWR(7QvjUxfmt-;ntF5 zVl^Cf0O`cXwlK9R9NUZ)pqh_74d4Mc8~YJrQA;#LNotkB?_Ue}^OxqVvo?2lK^#|; zg{q50?<4VFr56>lxv`yF(rpLi3U)bw&n~~9^*QFqyuKQ#y>ME(Ln%rxA=;9584r=L zHSS3*Xk=JK?3L&!1NX-&xJGKq-{?x(>8BBvj=>Le?a5$08r)=xX6sL$bbB&ReygrJ z&(f|cttKt%gnW>r5poKD__)s8V*~5p6*cUg;-PI!143(?vxT~OLh9XL-8#}6EP2D zC{!T3#hMUZ(|q)jj3KKLrHFl)p{(Nk8?=J>&a4$&9LKm6!Z6(lbX7g6lxC&c+;y0; zfaM|G)Rc!q&MELuT-CeV=(@)93t5PD)&pol^7%-~ykHH1vJzbMqDRamB2G9re_5|d z&_KC9#&V6{!o}oMu4zEAF(jz^K@&Yg8_{2(n5)EbR$@6FC|n5We2Cj7g^rB+jONEI z44ZScMKRg$RZt?kF5Ir`^+r5l2iQo#ge3amEFqyWR!q2mcE!DDwc9BIWXKcfQG@me zAs~_ckH-Ec+>cx(tz3^0&=~EXRLU*%OEi&3bymh=93T1v_oQ@qf@M^LQxMn zAT8{NNX7|Gz&|B_xqZn%S%`Tzw+`*=?t%Gh-ky4yxH1G+M&V3mTm+-dO7JP*_YVAj zg@gOw3HA8~(?4GxhSP;)yan?aM0#qbX9D)CH%Mm41*uPuXO1G_c4Tsn*DeVBoNmBT+!+##~zC@PQw08#-(>t4n4A4~;j%0AnF z)&O^SZlzWm88R%9Q^atmOz1R1!hMIjT1$`tNv%tHy=FgN$!EC>w||$*byo1VB-WL( z0Rg*@FAayE+_?tZQ&g+1@E??#?7j~UV%+?%v*EyCB79hBaht|PF~9R4ZG?`$GJ@4k zQ>@N$i>Mqi_bMLy#86NNONU`z2YBJveVGC6N z73h6Q(MdAdv1K%en6cc|F3tMXv>22d=2f z8~d-KWTCFT-$UG?$)aJ*a>ld&rtOUdz^HlK)`cRhgn9sTTo;3G6(QO z$Z_w_FX6>RK!3Tf-Au@urlyjtnzvy?!w2hA+HTB@{jr~xZ5@fo;E|(0h5*l&!mPKP z1J?@g4`%XNfp~1t3G?cam8evt^+WBch@Y}Fo~6g>^*rxuErOC4)}EnFtx4M=xcB$U zbI&FFO$TF3!>OTTpr%vR>EbZ>>%?wv!lX&8&b4TgEFFxQkl;&gU&9n>{xUYqYHmlm zE=MofA@}a$`By?yL-3H|IdJyZuP8uIM!eqBh#aFXp>9gr*;xucKo@JFgb>_$rChRj z;gA{kxN2nHKzTgXn6Uktp&gT+3I3AuyPjX9iWx$1Cy7lfstZMYjYpgil}+tawmT$WM-&RK3sm-J`O9flRueNSTn z@rJ`bHJ6pAbTv27mY21TY@IoZAi#sRUlsyrS-)kqUzZlLv+By9yd9oF^-MQK>&8W2 zWJLY!_Bp(**rtr%ksNAX2?Qcz+tZx%=%FEST{S3}WVxdjw_FKn+Zf&l3L*ny zV3rcq?t~#0!gh<*pAa3`quo!hh*o%KO-X--vzhn7?}ppo$BW3KcR5W5Vu^255T>Gm z#RgI0dXV_x=k4=Y%V?qEXly^OMk@y zYFb7E2ZUTozZBC+dv4^>!}IMm5ZonZmXXcK zXs_5IFhufcR^DE9z?9(yREpEK)Tm+|zj^_freGaM7_-y&mWAe#e?2THE~P;{frP;oSYq?R`p2=_y9r6gbTvJIO_pnctyg?#MWNmr>h{hrKp9_izHWK=!&}svbC@(sK z9uaM3>jdQd+t~sc*GtT~it}a|3y&6;W$jRC2gbgn?NVu>_i`%p@X-v2m%q^9Fa8ID zL0qF@(1?1nzzMM0su-Y9Wwb7Ud@J=AD!f`xAm*qJ6Wja=fBkmUz`*yQs5a zEdue|*t6A+h5IB)*aMpD_G&($RGlVlxMB1nc}sUiT-D?KsbVW;-J9jnx>x-EeIDba z6hZbFWEhXmZNeozu?KnSwTxTc$IT^%&^uq_pWK4zjuLx^Yw{KLPw};3KmmmESKPM zt(KTi9xvePfuc*;*+H(NSs@2SToQ>c_c^np%16c3*rh)>i#UeoKigLkNv0aotTo-C z;bXpKxd`!mA6XW*gi)TBq5~_XWjXt>+|q&+_xSL4R!Hi7W6V>9k@^ep**kVwI0Lt| zftWndD_Ef6XHaxq&*4<8-=OGibWI+eE=~b2#gWAaBU<8tp}$2$wNo`V#rw0yj~bu9 z+U@Y;1)X2FL=3bQ~UB_rv9FE?9JI|P(W4-GP_cH<`p~EU!kSE6%6CK(Cgce06UZa5-Bx%bf6IY4HsDu8fEyHJ6bSKML6^= zmar|n--b)oclP@6e)|w`6LV$bR%y=}OW!|swJeYQ`1#td29>)&vKqr^3?XeB%~-vl zOmJ@?xoB5z$F_9`su6JFn?cu=qs6%R6=1qVkd;nxHsCQ1<0$*dQ!e{E(;n@kNzf=R zmQ+oM8^nzW^vP{rIJh+(!u|VZTF8KWU)$tp#ll%W8O7wW>9T;}bj&n>6JUG$z((@$ zmC?$rn0CBpj(;2Evp)wTw{R*z1Wfd57yeM3kxmiaGX=1&{m-5VIEhc4)S+dNR^rvb zojcJRq9y1F(32T~!<$%W%!v=d1=P%KYpB@SWqCbRs{LyCwVGPBI*Z8Uf%%GavCJvD z#W%5c8CXq`n@N5X&Ad9GrZ1;gu~2Ib`%8fVGI30nN9Bqg-(`*Fs0WKmh=p~KS1kys z{L=SC*9*fIh`%9W^5ZPtbRfC+*qgr1Q2eAI_XJxmr&vTiZZ(!N3u+|@Ytx6Cwo2Ct zEI~l;F6nOaRQGc^Lq|&6eN6T*SBzs#eQn1NBI~0Uxs1&#lI1uN0?(-h&li*;X6mY4 z8Vf9Wj4caxME#GqLt`+2rpn7^JET!~S0~De@`k)co(7MRkfhNAzDQQ#kkcSk zS|X=&!Lt|{)c6F^eY%Ks$6IGRPR-6mMwP&(D%Ic$bg@%`2zNvT|mH` z;qLii3`IbjhZ#kmt7;)dKf_pDp~R#c7k^zKC>qw#)1uo4j6#x?(Q znUBxg4MiPbAR4$S@KFMwB}`AI%2wY?-m=gI4imI6mxR11X(gB>vF>@ROyp3br)zuYQwQALl!#^4lFt$;L8r#tTdn=1wUnfW4O{Yj5eT(pPR<{ z@?8_k)8c{GZE>u9B->|cj}?45_XYKmR}WSt?a9whlH1%3NwUj|pIhzAk@9h0ygU^b zOYAv7)NPtrO~Y8_?J-0ec!@KxG-!cHS?;5>b8=yY#C#4=MC+73z#1YboZL29O$;h; zKnDVJw|}2`BR>?P6e3OFOk|vjmGpn%^q3iO!@zeFCZ#-7tk#&K;!f6;3v|m07ztb4 z2CE|8$U zfbVxrtk3~#K213MDl61fiFw2e{a!7?R({96;-f8N7%E92bLs`sXruK0^FyE^V!gUuE@Ux$4xw`WTI>O)vfV-zS(*ALIn#6I zref6!OT3D}%on7SX1Lo`{)G=%Tof)Z_EtYCiKeT;?4qOIzXOkjLs9oWaM!JP!4hBv zv{cMFSX34QtA*Vknbi(nj|>}DaPR1awn!8xux;>fJB7daADBG{5Mb&Dxqo$3@%tx^ z5PS0{dgY>Cr?+{Wci-tJE36x-nCnFq^gv}qP+uy6!U}PAr1D0@!tFU&zExF`J{`w z+{eawH}1rpS%}Q8%FD}TI_L09?-ycW=giDND8A(>-#g9-%hp$(D_BA8%UnIw6-Ypn z)BmP_q7OAT!y3@D~5bjT7Nxu z>Wu0)3DKgmRrxJM@{!RJ3(=)aCn~Dlt;ON0B=ZgLp+@m9)W{sDzW3G#d_Fi7kc*P3t4 zU!KcVrBberMEF^8|BkPO{NxqSiL)e}bdrT1GiIu}!aL*khEwtHi_fpVJou1r{N>KO zryOZ~6J`!OJibt;`G8O3YH1C5Mc+42AfIQ?24dwdQqpCj!M|Xcce9c}?8~K2TP+D7 zdg3h#&8+b|qy`qzrSBm*iGo_>_nv3WvvlBeSN3eENflf_J+uzijtkbHb4Ag_1Du06 zR8TnVkdtt8DPHP&XPGWWw{o-2{bCZ*nLBxTm45`2PVeDtGJpav46n&1UbHPS!hE~1 z#yopIZ-sihU1aAiDj1-g$A)iDmvy(UV%Yg``fUa}!3Uza&M`?} z#Dcs8b6RdbhT+DB*T97m`hpBtKdbNKVW8mYlW-w(?0rboC*zmu^2>66J;j3YlvTi= zt16UgAjIbTC-jxN4~wVm-&6To6?ZI;>oeKDhj<)X3hC4AFngiph7aY<-7R+-)Jok7 z9)<3;6dk&2g`jXAD{dyi1D?r6MKS&e$jcvdjgift<>ii<*^H0XfT{4d?{4p)c`%Y@ zsml}6d-9U7L4x7K#(NX-uKK=50cqTvH#14IHEC3DdwZS)T6Lo1UfeqU*9yLwyPex7 zhIL>DeKn~BqiIr0%wmC1!ea>GLD*kfihkPSZnIpb36~p2WzTX+?TyQX{X05`FTC%J z*8rM9(1YO`zli*WbE=Y|>3{5JF(ksI6Nkg%j$EM=DItI?YK-3+O1HM6eV72l_vWLw zX5bmtQ#=6M7&rVPp=)dB9X&qs$F)VAVOFfvE)&+0c{TM)`zyGU=%=QGZ_( zVfiN@LK1g~8Y$jpEUR9QU-LH{lbZ`N zfI(Agh&GgK+OseE7UK;)rOe-tWg$~5D5E0xjgy4q_fQzQXToQcd2PcYb1%9bFA8`q z6!-}M{HZ1`LX%t9C{;6Hl&dZU{p}`!r0|2ijKyq&W#`jai(!5jc}bDuSV5Sxm= z`YC%zyb{`7W}`B%{osyJ2n;VRMjE{BR6=h7)}V<=KW5*oMh5F8X95|0)=T7Q#h^9j zRZxm2Y^={94=Xonrw5VmJ?*bRc=21$O)meM@6YKlkE~80OxJQ;3hV)Jug6s!zFxze zAB{UACn#7cgfY%952+Y!{48}ugL)bsw`H-DQ-Y@->aQX3F&rQKSzsvxl(N!zlvU^> z6p%^l%@!%eyI8AE7G>|cemt+`BY-ybwUgNTiArTXkw&;&9xbRJ+GS8szcJGqQ!Aq^ z;rW`&iD0cFY+7cbbq61+og}#oe+_rJBaBY|q*n7c(8e;+ORG(_ssqV{!T2mAL5h&j z0fy~T=L(E-{jj0-TYR6DSFb0TSz7I+0DE|IH`@+Xj#5z<;xE$Cm`(uUU@cm_g6exkd{g)Z zt)tPhO?HqjZl`1a5ZK=h`&m(B`_6u<2WkfBu37Qp^K-|-hqHLR!&63eEje^)GN30a z1_pdt4f15=!3es~+zYquTZ^bJ>8b>LoY^(X6od)jaeq9UqQ|4^c1L6IiV8Bv59egV z*7RuUzmaG|OT^R%>ylHu`&i>$BK>)XyyDT1(V;IW zcF&xfD2|kCOzw%n(g^x3R)3DbwT^XTc7_FT1|wl_-4qPpalO}aRuAJ8l3JYVHW-c@m4mWQ|21d7 zMV+^pq|9XH`$SggDcgl(7Z_T{i?BW{$S10ocq6rPBd=X;!EkDGT2u`8m>D(T6IYm7 zr-jc(wy7GOt7b^I;MN3MYQ)q)ArT1fNsmUtp~1a*Z1`CA0+Xn8TwXJ{on-(R*9|nrvZjYe!U5Zbp zK4(ika6f`0ZzSTK+!t_K0d6_%Q-?sAKc!^a$k6XxYS`PvUHDC_HA(cLO$(NCau>aV zIArZ0Hxf92^NkuU0Ia$AndIm4Ezb2F3-x7l_-TTY4sJ|9Tu3SmL1FrP3w1%dnFpO& zO)Q~OBTf2t!724AkWbxZtO^yIPS)kt&tr!#EZE&Uuev2#-bK}bIgr2J7Q^@zdpPYm z6kU|VDe`^yPDhG2VjgVe!YY-VjdqlPzSPEniXd<*n&~{^cn}k>n|hp{s@gfIv&#|z zh`{j`JvZm3sE%Ga6TBWg(oSW>vlCoj_<8GpP+`ZaJ}_rp|3ZVm_#gbw_u^x-g$0N2 z*@7F?cE720bRQiiu8^EmtFH}MS+$`yh{N0%*gq1EM+wrWeh1!kLYyK(M-44~Ju_vp znSX2c`YA>*PMM=`+lSi2OWnNwn&ziZzSa)F%IFXjFo1R_p&MU4;uJqg}WLvh1Qj|0tIf`Ao@_O4GX3@cvRwrP2VATJk%Wq*hUfkQ<1Oc)Qp{kGn4B5wN@t= z?z58osCNEHv}QOml-fQ}gv9Iibmk@!s|w7}v`u!cJ;T}X4)9)QN6PeZfAI`Mnt@a1 zSZx){sq!2#OxmRN1=~qO^1~gOs=waTc%k9a5GgHQj@<@c*mvks(V23_=6%iOv>tG% z$`^;0wEPDWra`5DzZFOa6on~Bsp%OgR`V*g+SFbi|JNv!A|w@UE2AWL7>;~J$CgjQ zt<+)ZB;U?Egdi|#=*IF%dTAx*O0^g{1Vi%&d(w9alc3t+5er1+9noiPfS@g@^jeoj z46sqhRe;_mDx>c((P+0J{&@Y_7?!3)hyYQH4Kt*ae`UJak*rQ%%i=j+T;S72ijiNy z2vm)@E??nlRGnJ!sN|2;u|H1g{MrHImnCEtfR`%Y*=U0a2KUm6|Wl zj=_x)k8>>WPE3^Z^-2y<%-!j@?Agehr^g;gV=F2&4NaD(i|QuK>T#s2vDpz=_N6L* znFUzTz$N=6qU4n132`Lh;x%e_P|6ricWMxjInc^4=DnQ=#7s?T!%OX^Ep$2SAwZrM zXS#OL;BCk)u4DK3xQx<668R}nb8w+IT<=HeHbtZ2G-e*TfXn7 z8oRfZbKa5g=V6{3V`LKtV6fA04pRjIEXxE$)v{;w9-#s$%8~&x#6wGrT>M{sN&9Lp zHF=CLPd9fCPUWy(?uIWSAe2?%UF>ZpP)_m2$tn;c`x{2W-LWYI1Sfj0c=4z&o2R!u z)#c>x87C=_b30G^YnZ54RtWRo^*;DtIC( zaIM|#Ps$qd@NwbyX?g*@{nTIDd#mGryLMLwG}B8|4Jr2)GKk?=+_yu^itB)KXO_pL z#;Ru5hZ4)OAI49lxuLkB!Ysuqj`&n6bzyK=hZGasNw+4y{V>qH$MYke%2-^}9?I$g zX-NQKDjqCht&HprtUp7n+rQrLyp1-(O4nv}@?xQpy;B%Y?rx$vPS4l@AQ(Yk=Fy<- z7E(m98ro3Tu7*;>#+101u`+*5t-P#3Y05boxx^`!4kw&bP;%uGkr6-dPN$8>VyE}X zaA3kC4C!5ndGp?cmz>W~eC$;h1+)zB$iUyUDX{Nn$-}PnVlgq^pB5u*!@A2!mX=d& z>>sHGbJ4sSmcGPia6eOC)R9vS=Qr49OgbW8 z(cJ)S5a9$UoKEqg+Rf%)(xDET%`h&HXkUZA=XYAo&AI2Ng6d zzpT!9=pQ_Yq+g)P4vy@4DEJps4QE=YR5XAz|FSFeVO@FGKwyPBl9;AsC}OA3u8QqtY&uLx0x?(hZlNUG zPm$r;Z50Wp7!Q;lH5;ySCvu#O>p73kyujmXxcR;S@rvf!OODU~vzI+d9?*gYv=eTy z4bXhf4k?m}ujbty(G1ia3e?*LmSDV>x<75JL?lA|Gd?|;9eeI_2pU`%HyB73fYm#m zOk42~S_87$)b4{QepH20BcIN@?yCw=dF)ojG?qQsSk6G=ayo$vuvhawJ8gWv#iwC_ zv#Uo23^`$TXSIlnlZiPJDl*UNRR@ENHZ;)TC zJ)h{3JwQSOyfUtmymRotAJt%Zl-KFV%d`Zb0Dwm;OI3w(9-V2MtxU(((3@P~saD$) zz+{nAIjr*cXi~iKcP-M=jtlurnJtPTVSYascl-k>#~SVEmKIUfG>_(9Rot8lC5!%s zO~#X|NQ4&oYR#_{A~`)g=CjK`sCBN;TyXanxM_bZTj|XtVEUPFMcizl{}@B@k94`w zQ$RU@e-|Eh1|>8&g{}95A~GqL-R{ze@8TMPpq+UtxX3Td!%%N^=vGmzQ2w?h<=L|L z5<@w!qs-BrEbgQk($YckEqhAzC(RuVV5d#Dr2I5my*~4*ozg$Kqhcs-vlv5`OpC|D z5gm=szYN!h-c;zcdG66DBhl)HZkJ{4X;iNo?>2Y-C~MBkqszBXAJO4R1e+v2u@rff z$T|LUKqn&g)|31)3@OTYr~7o-$Zb}2RbR#?rssF187tDFU_>3kdiMWt_RdpPF#cVj z+dle>bacBs_6O7}X^YFgYb20gF~c8ihV}}@60@270n~b2w*zy*!LJkr{7ADz8Ip^e zmZ@~3_WV^`dxLsV3FQcps>5a6s7j{H#%-2Z3z2QbmIjcm3jgD>Tz-yzG%$T#>+Vty zlq|&jzUorjh(UrdmzNCSvy2xh&BL_rc&#RP^j$tetzzy_i)Sp5nMNW1-KErC4e89t zP!=`JWPT)CCsk)Z;W^wpslXg+%Rge0^*4LIeEMTb2jzp`m0UF_xO5>|4y4syDvT`i z3iemRYi$amrWD#!bjG_0e7!KS9=hc(SV5zlio7pR9<`TQ!T1~siAID|YVGAHP7ZTA zs*oy@&XKyvO^P@|xG%b`c+BY-@oX|+74l2=X~ST4^_V#gS)o?H-G(+ z76zNO-k1osChTG0yHDa0No5Iu<|p!Yb(Yq9*I)BQ&H@Z6*-}v0+N;miGP8x|%vgo@ zsypQW7=eHD;Bswzx4ACw{;7O;N5LP?c-)E&iMpg%c-7cUf2Xm@n{~ZaV*zA+r^RxooZSFEsc|FXFFN z^{!Q^&nIb*2_UVeuI^qil@MTGY5T5YW{o5zXYcyJWta!Pry#PtXh_A_Eh_{j61Q|4 zqxtYB5r7hB_pOv^vx%Wsg8S!Zuq{0MwN5bpPHi!}&2tJRw|&@;R!B?EQBR(0JQa3a zr-vJ!SYCb2;gAA;CDRJK7E}@j^DMg#xBik1amD??75Ju188=ynY zLSdWOU)ur((x=mMDLyggs7muI7svxeA#EWR^!LKKpRvEWF?Y%D0?ujrMOVXui`h)< zlw&Y|DT%tp;>`OTSF^5GI}-P6w!?sX;lOZO|6Z^U7ObrPif>IA;-nEkAv7GyKq$UP zGi=4ae1Ml!BXg%*KHARB&i$zfom&(>YB03w4!jYYd;0SVs3n$dSW(ikM)>vV#vW7d ze$?C>Dm}C7IND|vF~%FPc&fGSyw>##*j|)lGrJ$=X;a+WTy!Nd@7x&2~G2{4? zQCDH$gdneEWZ>B1X0a&U1n4xlxWzJlqcvk}E~BR!IH_h1ogV$YXSaM0$27>RF2!04 ziFA~31qt7gKmz%Y+!}QE&oAT^z7fPaxBiF2=%Q4mD~arqBLXd)i<8+>M>->!&P2b!6@!!m4k`^C(cW{GvnRNLM0g#bE!-> z15A8dAo+92m(m12GMF<^nh2_jg2b?GC< z0cp#{M8N36Q5w}n=g^gkgj}s#^hk!!?}!sifRlyvTrKr3sN>*ZpnxS_TS=s0Wg0rV zF>pO)L{{-SIEeX|`CWO1j~9<6vyn{}&>y@=J;ioSt!rcI;#dsaGmI1cNgtL9&n{VM#J@i=4zzbtL{ zAu&`*WPY`5%y0{xS`dmZosl~V(_c{#GZ-0EHUB|+_DH}U#>S`HN)_g>na|b}91yPq zT0so2VUGdEFIZJ0z#}c;n8wD)U^cI%&&~( zz4$GSXpMJ(ChVPLb*Rlp_%;`qrv+M%fR+zN28o$NeWq`**?S=BJvII2F#os-5=Xzr zNi}H=hFxZG-yced5s^l(M6ueLIX`eKUPg;D9bBNGpVlDNRZQOp&AZ+xb{=v4%<5lc>cb74^Sf!PqDBZI~Rp06w=PWfbIJicFx3jLwL z;sjFC7R+%P^B8)<{l0lk1Ehl8Y-7h#MLw~KsEVh*Pa z*@{Jst$9R30aQN0n-) z!bIW?HE5e%ji(tlhMwCJ^%IjW2nB7Rpf01!H;bv=Gg_%xjO8?_qO)_s8f!nADva#a zDKB@Do-6ur8GNR0cQ~~-uDnmLDOsH+I9~%x_sDpa-N!+*N{1D*!K_0boLkSRQk&oh zwwrYyvKv;pZWdOc)84=M2AdPrDP=I{tRl8=K$n7 zy*9Pm!%bE7KZo5&Jn(QbgtzNQ3$8aIl5&leHb6WaXCBLHTWxO+tbNkC`*?3m1uE;rI_aXgCaFZ>gohGM8l#5%MWr$8-m7*oG__|HSE`5x@6_ozKS&b}GWH z`Fo1_t+VWMK8-<;0I!GgkubpBdgiD(HSc~5g|=>@XMU* z8W+R<1j}@AGlT_&)*(9g-*hMI?L(ROOw6f>h4e`AZCyFj~f>uVhjOJ)!vvF=F z=n_w!c7D!BsQc|QHL=0g*Dd0Fkl;D@uD60uOJg` z-x8`TL_SYBx$wlGvzRYAP2Xsu+;L5yHu>o&3|H}&BS5yKdVE?o=rnFWrS+Qm*=TVA z$|3IiST2bqsmiH{P2~3d_^lCedWkKmYW`I)JrGhN4Oic70)@Ulok;w3!s>NE^(JV>pV`!RaAo?1*rM!+~ zH3-`)T6=_SEh=TK=!sIgp~T$|+x=!}ly`xJeost*V5t%(kM4LJ@{sFJ{r>UIAVVxX zDn!(V7C%z-T5A*MoS88*G)`0OL=3(jIY;Yj7_beH?aOL~Z5%Ubp17E*k{tQ;`PM{h zWU2H~D(eQ?{F)xMMEK)2yn@oA#~VuNnU8!UcJ6UyNRiji6wwb}jY6C8nPb>5iGjtT zSoeOvbbgy>XT3YPvfZ=&$oaIlL6qT}58)%ym|{w()O=>N2kh(G^nQfo$og;L7o~a?AIcDu*4-*ZEy1+EAK8}lP{w&Y66zKO3AEQ*+9gm!oMj@(X07)Z z8vLafQJ6Jr*`p$5$=931dJQo-YP|*JjZ{%JozG7AjAI6O4&O6gdG5ClvrxhxfX+BA zZhBbBXKYT#E)6qdnQO_K7ppjvTek{QQ5kss@1TC(llG^ED6Q!*7+6`G*Y`KZ0QZy7^Q==rE?leJOtsp2ZL=ral49z z5Y^svGapDBgbZSg+rBH_DpvML)#tbpDf!RUDry&w5y0X#-AYYIjU*#VkMt&DT~D+X zD7HAT(Fp!744$h5c-JDA=rAUuw+bQ-VFA46*8}8*AQE=^vb*@U*3v1YkKqZ`^uG7;-?tYMzbI!c}q4%6MtTjmmUO50Z!yO*lcQ(mVBcK@)WgSg7`(u-udPy zi9vy}Rp0C^Ri5-Qc0WGjL})VvVx zGFB?^`QDcf$GiHD@=1pRdp}J_l{~L~#QQ@9E@vZ^hU}HeCaI+v7{EoMTHmoz+@Zvh zFByB1E*tNjpcjZ~QHFA@5vu5Y$H})T8 zaH=iP--}ZXi`M}l^nduL;yTr#aZ%`^z|?aij1^yqSFLrgeiaPfN5lRK3}e3D32o@7 zeI6MC7R}Kp2^2G8P~!B0QK1QM-%;_=%%D9{ChZ5@eLy*-fcxGm<2 zd3C=|xh*KAU_Ay_9p$`h~e-j|qNVZ8SB^3Uy_ z6`?x&@->m3X46n>t{$M$D+4H^ymv6vY0q{p461p_^L77FO-;Q?2>)23$k|l1O_98Zp)_9h z_1+UEov>^JYZ>_~qaWO`4atPpROj67*}UH>(mF>06^!g}uz1DaId%EObf+et=d-t9 z^V$W9sWKmHTMi!9sS^~F>t}Ke0*WBNOMcouL|b6UmUWJeL{!N`p7NdoX;Hnm{BuSM z`fOa*aSlg);a}~>iEj)ja6o3>aTyLp4R?Kr#rKOLPVO3v+gTNL?4PSFek{AW%tp^c z`8$z%O=B>aW##hX2h1j6-m)~`xqB&W7DvuU%{RJ0CXgaAUtLJN0rfF97fncJ%ecdF zY7@iF9SBj*B^GHr@|TDVf6Q##cpr0CK`^>Pz(o`LC(P$$XZZ<4OEHs5@b@Gj0SFTD z#}`f_tcFK%TP=T$G+KHR!>+ZcqOVoBQ4x3+z4O=Soa-2QB)TyZ34Z}Q zkIBskloyK*2(%3mn*15F>UR`m+}6lYS}sb{DqX2mJ#7T$61_Uy{7`4SPbs;r;$Ihn z)ybR>7Hf{Ouix)QmJ)aFB`I-J0F}wn@XrOR6$Y1|Vm>H9L@bUo4o&^Zg~0s@efK#9 z>B@XWtVmdmawi0f^n3~~4j`QP(S~mQ^hE5>y0>8uJ7uFvN5SxspEQboyT|L7euKYt zAqpauAJw?A^Pw+h5=?AgZ(yaUT}@Y}#jBLtr2xGXjoeDX5PrqMtDW{ec_CQ-?3HhGIKN@bE_E}TGA2PjN_xT@lb{=GazEB=2Yoh^8;RN) z?rNoOBFVK!1Gi#d4962wG*Z*>c?0m1Vxyx%n4*s+XFH0Ulj=4B388~8PU9N6OygPf zT?vK4gyGDSVN8JwKaa$Y#sLAU&ON%AVfSpJ^%?B<#({%E1*mH}Ix(GqPj`Qi{=wY- z={Gswk}BFd=9uQ-8s3THHSQ}#|e@f0DGqm2*&Wjtz+#ls@e9F~p*W34# zoXs0q$5hJvQVc*O+{0K76|Dwwd&i=)|D&BWsSV)GFBzDv2LBft{G}I>lQn;L@4?OA z9wgG$s|S*zi)}3;ftvnFg3&BxELqW8k8!VxqWU0g-Mf0{ZRnDd7+%GRuGmJ-=Pt6K)IZ8J3%7r#B$x^7mP{ zO!~Yvw1VmtMH`Nx;dMQ#PCYOVr;yH-4A`im5e8PyR3lG81|;q_qRh9ssoL!o?N%mipnNI7ythxliN4D*nn?YX@%RsYG_Kk>XNsYf z;W1972TlOad#z9W*5kIHLXi`#*&fLr-#!6z{2A8xy^rH3TM0}bW3gZH$4RL-SymEq zc3+28_w`@`6_KbRBOu1ZNfYQp1;w@dkudiz4=ia((38ZG=Q|B&Hb{ zx)czFETHRe!)gaQHcTwnq8ZG-BYEoz+E)Fa?(IIYG61gWIt3Qgrg2r~XmSdy^`83t z?YUZZLND5C&zT8D6}>Q6tat2!mq(PQH^a+mTuO-V0)yFKnpvzDc{LOrbbBO2;Qnj+ z$wSO7{p`0HsgFB8*{G=u|hW(oz{gFYV03eBT3SEG%@3A5XhTx7?&JWGdP zu9wUP43i`i;S3_EPhf8e+0cKpP^g>Wz<1_%r|=rlc|sE%o5=#{ty$HVxFS}q(Pna< zr6Q-|rYDfCVQ#2i@lsxkFs{u3R-C;B2;F9E!|#_JnIj$Pu`}{>wfk+W3_?J(u?>W>%=uXassEpduz9eZhtZvuBRZxt-N19-biM-y(V6|S2#b^Zj7M- z6gZ|DfB)%u)A2_Qt(qpzJK(sXmi4fVO#RO3>fOjrW3|!?tnf3xr89P32G!*`ReK<3 zJdq(}L}$KA%>M!F_b7g~9iWohxX6%l(CSzO5MQ<68-~8X#QOpeT=!XzRq%B~ z1vaxzG_;rsz-9Gl&cpz|Ma|hOCkD7y z$a>Do$ys{S_ksgA!SeB-kkG;Oer6eoHc*ku&t|j5r%=sp4(h$q2kxDyHJ+F{jSHb z40U?=$8&dkMCa)mQI%$Y2DEbhu4DqiTEG3Ie_2eAf=EM!!6p#UbzP)min)<)Cp8lfyYkMM15u`(XY~cHHOJUO zFcyKAOl~i}f2`k}5wx7lM*zh@I=@;)x~!Ivv7c=8?N1<<^_ls;Wu1{AXVx};=^_zn zm(B%q?uKy&T4T_w)7)o*k?cdc#xf>{OicNcI0P5iY%zi4*S#F~-U7ki^mwhHS*$#vp*!=UiP=cf zGbKzo*Hz8iOS$*4r+dcS9N%UW68jve--6>ko$;TK8;sdNiUxPg(YYsm*Eu)S5SBQj zbq7Hh)0Xf$i4HokrEYC;B4WL^R9Mi|{5bgylO&*#%0-&WB)|HBm|1l)XQ~(23M&3= z+Ml-NEp|2w!jg;pRJvsbtJow&)0Xy&RjN4nFTIGIf9XZcYs?~|9n#Us8pE;rwvfe4 zwOAOojSHItWTono5IL07GW4>XjgeUR=no4|%anwq@E&q1?aa>cpZq!46ZLtcW{=;6 z-zIB`3lgY*LwyYw{K+}C85y@rPbmMO*iC)~N%a$iCBd`8oz|Ovf$=hgxN4=Q2Hajr zTddlW>X^zjeDD3i{z&plD>2G$%8uqTr~4z*H~iT_)4J^n?D+`W-9WOzpAJD6gHV}G zJPhpyVX;(z)(Anx_o=- zUF_^`t-~E{CHXK*p_z6m)RHh{3?T{H>aQd(OMo+DqnfS~Vt~6xwY5hfFEauR3^8Qt z)pT&a#(v?j`4g|{3A2Z~;_~u|4p1$t1l%xk0|Dg>Kt&Uwj}U0GXC$ZJBHzJi{S6M_ zKFV4(t*K)Q9c8%5yZ_sor*vSo(HU1wbSj}WR-?kMQ!qwaD;~YHiwD2HSUb!*#!L_{ zbwggz=oRrtn=vrv1C6$8m=nugGqR3pYe^0VDz|4+xBZlBdmkhWx2g^hih*AD%EFcL z+f4&ABn7?D^_Ho}fFNxnap9qVR(U7+OXi&0&lX*;zQ z73#Ht%{t?JUaekG z#TGRk$-CF>R+zcpq+?mlx7)X|d6nUa{x(Kacy;V&p7xru3n{ZEMD0E|Czc7QgMaO1 zNz#l;+iymam)jo)t5;fISiJ)>yMqrA)kA6#Uu6~$Soi(?nH34>Ikt^6$0x;`PVY4? zknXcTM{4A7A{14tAj+yS+zw*y+V)zUBj?a=hrqovQwN$in4=>H2vH508A>hWd}@fm ze8(DGSf2U@J5@e-jrI8h??63hjD;WI_ztjb3X^W>EW1t|bTF_vS=GKvyh}P?%#mJ8 zS~X=5T&{=FtWLYQ`C?9ybPge*j}<>Oxy@3zv*=5qthgiIp^1_y9!e*@*T}a zIthxxejouAx)Gb;L_|EBh=gAl4`12($#d!&Sk>3kuIfB{bC0BH-CDN^hfw(YdrO1S z$b+X0RED-tKxfUkXA_fl_l!RMM%5<-d*4(k3-2E3 zdxSwp5)T8?QK3I7->IMkFoM;LcW?Y&M(c~dva<5k-t^_cO)KQ#7G52!k8@#wrUVAd zAL>Uc&S*}urf=SB#u_eO=exXdHRIXbIro>%QIq9yyvicEsJYy}FcvwTS|SPznZ zY|=4I*r8C7e$3jYQX5qHzcxt z7SmNL!(xr;+)>^$-__u0ur{YBWYnx8DMX#8z346+85JX`Amoah!+7}p!0LByTqRjZ zKp!?6#k_BtVN5Gz(EU-jZ*l~wZ6Z#tOf=4L` zFO8$$=dNhq8icJpFH=K~ZJSTAeT>KJHgOk_!cvcwLd!VGCZOIK%k@n15o)DWIyOO- z_83H}WA{9tm&MFMKz)i4zM03NesdurN}$~!W#~#_+AGF-Rx2^orMGCgC$KBycgx4n zSS~h*g3!R6U27XiqxH>roeHtQKjK9qh!dv4J9@<}Ym$x2G415%K~1bsdTaL_5X7wF z{2Vht_uE;@Rpe^ZnMPS1QA996?L!47p~K1z*qnl_$mrlS7bMOi!Hm-^^YO0BFxC>+ zG`TLHTG2`nD$1=*%~pU85v1|<$FzJkPdcCUyPeL^0r)RTs{Or^fY2=x zB(xpHn=;e$0lhy4!{k|oawHdEI<7zsM|E&`NZP_GDT=O|BtOA-46_3;P$)F|KWd4i z{hCHv<{PVJ+|BU8t``9R{wykhe{U8Q!vD|CqWT-@{_QL(MFPD4SQGiLXHh8<{I{bL z5x`$(P5r-LM*;ZfEUNz<`A_;^ogHi}U7Y_X2JrvuYx4il|IN!>!S=bF3 zSXfNh%-9WCj5rvX84QihSXem!rTB~{|MGoc{x6&V#mvt7&-(u(@}I2#f7SdiW>&_3 z`k((1`S1SsC#N=sF5^PK|J~>F&-`QapI!g|Mf1N{S^nvN|HtM3n*YTQ_m}x!?Eif> z6+0&b~-T&+h@qe5D#r}Wr{4Z3d9oPSF=YRb_zsCRG{4e(ZaQ@f->}~%!|Lgz6 z{Ac<9Uo`)ViS?iJpZ+2FPuBmxYW^29^FQZ5|3mV>qW*LoENrZdj7*#?42(?dY>X@% zOicgx&EWrR|Htxg>d(r^@X!6FT5i;XYw(4K2x|mA^S(%*jg(v1!NC1vr=2Pp~CUyR9A7lNRa%7rUFDwanFII z1m`ZG*$F?(Dt(n-eGK&mM$7DeSEE~H?E9%NjI!LE;rYL{B`2D=2&L;~;%w zTjy_!J!hVuiB0@G;nTU7ot&+WsC#SZC;s|MwO7hE>EBWg<7?O*>1123yt$u*0o&1m zbM2wQ6?=Ye2niw#gLCJR62Q>pCp;W56WIH-S`Xnf1aGPb(Zb}so@XvU(jS53B>(>W zFZRFuvGXT5`r((@o7H>wyQ$reaxbAYjv-ISlvr~kYloyT3ZmqB(9?_)d-S&s$YYrC z=8n%jH&T!`j5hMm0G5r%Y6+bW%&2!W?8KgWO>qSt3y$@@OVsffj_C2&ysM!CcY%p7 zX(#D?9jiXJSWqN)&>-b66ir2NxYr6}Hh#Ctt@8HyLe>Mo9+T}LH0Xv&GeTBecEF0q zceMf8%43+IyiTugr-UzSJ%c@Sx!5<`AnC%hBab8FgeXv;5vq-RweIb1y)C2GoU3iVt1d-6Zq=qemw9z6KS5c#9cG6_qBrGzg#=I3(S1jaCizv}X@YT2c65 zO)0N7bUPNOlOK~EV(h$g7zC=MfWCVk0$z7})u(>gPnHX z^(o^zCw7793OQFo>e|JjCH`7}S&>&ZoY2tr6i$I)0<3a!bqeBL$nI)Qh%md0?w2Kc zZlO4cV{hwJ0AJNJ2F4Q#;U`s}=;Ob*FfKs4gCN)hTjs2|z9IYqWEWKP#A&Z}RX3tQ;y^i?yGCP9*ALO?^vwtSI7U ze|9z}NekBuWpTo~kUJufRKfCT9wMv^QwHs)*wJrk;;HUQZDiE=L^ZQ{K=g( zsl(cATBPI2QCWR!*p^_b^74EWUN$<}YdEK*gt5oAHiA=Bln8qJAr8i*4wR*Es}R<7 zANb(&`Qazpa!4de!CLWLmbX-GSa~Y?CG=_JgL5~beU| zg5fHb7Qh(B`(|jn6*V0gfjZ-+F5%jsq;LQ}-3P=T{c}X@_jRt&?lrNDCRN5BfQX7n zE&S5W%AYTJaPzefK=D+oiH<&Diz@wu;tvZtc@R!9C|2r~Sfv}Rv1v|3Jj;v|mCB(` zWPr=*4vSu5SVD|NkEpj}Z#YQ_CklTE+k36;}=HGlTGNyhBBzC!EQ@@z5H zdHGyal5;fPZV)ilqs!Zdt@=BDBOap8wiz%7gu7y`2wm<}`wQ8b2Fl+h7dBwlXn4m; z#8M6?Dy#`_%#$NK!5 zr2?zaM=bT#uAQSgTyLWzJy{WZJ_~8iW!6PvKfaXi)W<$W^X`R zE(`Sz8Iw8N`;Ly$MJ)4AEt+~v?LezMNxer;c62YXzrA6T`uGbC{^Hy?VCjr2%ZBp> z8h$;)Mlve4=Ws?2Y05JhNHMCfBAKM)o^Mn3kntF!>#*i&iEsle*fNL#F#J>SO`}8CeS-K>6#YknpBP?Yf>x8cq~@-a6(hB?IXp@3zG41)UPe$nx;; z)9u#FeL-dq@K_{C7FVj_F-Pbdj{pEFdBu`=<05nK0?ZY{ZA0mVKuzi!Fy;wk;{i&8 z#@WK6Gvbky<|swEugf_H`&8mO-}n(<;1>&+D6n$HZC20)#&ad-PDuvppsF|k;?BE4 z*yp;*ae8f{Ih!ke7kea33xW(f_j{j16aUnfxYnF(Mg&E~v7lU1h~He}sW? zb2}uv4`fmR!o(45Mb@AMn-9~)x-x&MwJc>5I(1ErkVzeL;wkQQO6BtM!llvE3*d+M zMzfa@+(Uo>tU9r4+20M82jlUAWzM6HSwH|zVT8osbx$k40#a0qR9@O_5weBqu z_}|lrnv7G*fW}TA3A#D{UfpTj0*863FL(`d0MPOl>cYa(e&;xT#F1Fbt4sEJv zo>gjiINyT7QEMD&sMWUfu!^yVNyu@Ym=_#R3Ti9YU0Fh`jS3B}7lD)}wv~yMT6ATncL)SykrAUNzSpHb z7nboMa_R#byV9s&S&8oM8rFHj8*rrT%99$Y2=fGbl!XZ%r@yA718K5YB#USmHKq7; z6QN*{28vp{X=lIu|Ha-vhWXNb>4I?Cwr$(CZQHfWwry*dZQI&q+q-OA^F04PeY)rL zKHb;6=e#|0&Gh>4%ZwF~5m9;Px--_5t5(P{9x&q^meef6UWV)|n-eWzdyx<4^Ubaz z#)z!m2bm=FSTH&&{J@@L|c zO{Evkk#Dxs7*;a=>Ud#+_Br*GZlqScIzEo;_fxg5!C5oZift*GNXq3L*=*!09VW&E z-$8Y|4sm!C9VQ->UozAhECUWuFcg}xhTsl1^)n3t>yrXTGeFl^RZJRIzO^3&Sa(A< z%s%sl7OI6^TOeABKf7*Vf_9pc>o9_;n+7b`Dl4eLrK>Nc9Pkfb)ur~FENm3(?QNOx z(MHiM$#jDDw>8uN>Z>7%LoGg$fuKrgD-_lJ;HuxkyspfCMFE)0={2L_LRP2XLjVzN{S);Ams>ZqGXXH}|QAb8LpFi}8Z<|7svjepeFFIMLjuc)!Agkk4o*Y1t zxe!p;sKgsl+8U_ob&;e;sej05DrwLN`vOfbNKAfsK2=-up4kBsCPzM9KB`K4=g+5X&HIk$z#$0$`i5S`5BW5PNy;sT zn?RWdWWk??M7@qR|5T=1hnbY!M~=BV@bOX#|Il#zxfCnOJAfa@H5P`xDSXhnvTOn8 zP$Ovl^nfo}W~ymk{0`$iZwf=nwU`?!AToQ1rj3^$#zLwUf%y6)4}P4l64;)zI*x8( z@iC@K-W!tQ2A%wS zI=yMm9Il}i+@6-iR<9*XgArG5&xPlFO7LM~H9ObVmoh|u&IdK6qd7O^m;0I%Y)5lO z`s*#Zbsy!b+-lN<&qiadA|nsvrP0~rXNsg}vhWnRFQRaY31ZwjjI^~YK|$j;@K=!5 z%DA2ZHmUYq+}`eUt49uBvqXhQQ) zfuG5??EbA>MXCK%E3TM;mV(Bnj$7ReAUtH{v{4>Zfq zUVY`X*nLw};NpRLr+B$IP2)zd2y+B_Vjw&o+Efi8gs1!*5rc;$dn1(VeFg}-DuXWGZ;S_-nj z@`aalvrUXYIC)(-TQiF>X5(uW1LZy#lE^bt2>QrEQ5w2;y@y zPQnfO*VT@v@ld2d_f6!2sz!hBghPAdJYS2U9zkQ*2B9c`x+dTwC%B!DanwyRd94^2Z)mn(NV-9RNn1#V1K zZoc7QvY>s|eC}?m67)|WHRJSUp5(Pl0w=DUtIK#`dvi?dI=%X!IrRuq8;k!*+p6Ny`P+`>lZ`< z{vV`K7Y9r=FUH$38k61JlDBF=oT?l-U`pR-#3?&U7W?a8o`e@&K-r*opTP4zey&t- zFpJC_2+|@O6Bb7EqKq*F%)|b846Ng`m{y1(y>FES858%0Q$-`SS7Ht z_)4CQ*GUH%<}AjPmIp$*<9;0CW0;VV66o|S(8?m9bt27Z^xbVF641~?nY!81%d>1U z@JC?{ysQ6#4gQdGL-Z?KRFKVpivS%!hW7JuG|o>9ofmt51y4vazDlV`o;1cj*hXmf zCT9AP=wifg0X}m%+(GoU5k`NM&*pU5Tj2?QfhFjKJf2_xh@=aHHoUu z7F&~bD(BAX?W=;!P2Mk1h?{wLu;h3kJ{8dR?MEm%ykFN}4KgtN-4jxdfY;fnjtI5& z3t@eE!+I2RK3lBvWjZ1`x%+b2?dPyGGOoWAt3TQSb4pI?y1>@ZCn7rueFHhP->)=x zwsDm(^3@`1jr|8G#A#3}L^oDmTrg8b1yU@$z2?u4^5!-@u#P_5^eQ={y`_DCAeFI8 z47wt?$~>H?FQ{#IBk~F_z7`O-faF`lZcCp7e~D5^dvYx7kRyqI?TQDf4-e3k0A-h@ z9tX!}Y^+gLBiOzX!I_g)X8!U9XDD}UHcj?g5XIu*jaqN{&DH z2t4OUNjEuGS9B|p!R?HnVhUpzXB9uw?b)`m-L}~a;hU}inntY&T?*~NP|jc>&{x(Y zK*l&X*h50ednx^T`cer?6J2v+Yf!H z{~0@iENF(B8@3h7kw9S5&d@&<(b8L4kM=CkoYOU!tGcN{Yw*cdk@mSF({;a5vlK_` z`GK6WtZx5HekgD#j^6kh-V@IoVl4ZCj7O{U*W>9HAZHMrj_GOb6S2PC$OhX$>5|Hn z6Q4sR+L=w`$$M;X)WP!w73F-Ia8Bly`;y*!8V97pCW1)31>}GlLXw?=(Wu`=jOS$m zH8MY*)|6&I;cvLyM>;1cDccv(Kxo#V!AKyeO@b?Njr zG?#4xObq|TZ;XkjD! zJj>xw3@`i>fntv&c`#O5L;4ZybbN6t z-&1d*$ti|b`g?ZqCbsKs((k9$m73aFMMoUDAoJ%9n$XRb)gulw*Q(x^#R}O6obS_b z?kYie#0Z%$}@EY_#^qz zNoGsBp(Tx%@z=cbIB841&O-9X zzvezG&?6yzT}!cZBNwJvK0$NcoIiZW3K@3CBOF+}tSQK>tH4h0;e#aaYh+?(FSH7X zQV0Q+Nd{+nV9tJ8li-QPr(pVBjQTKBd+1l&W4t?8l319LQ~3qC3r;*WqvW6T)yv)I zZQZySzDv)j(GHaPt(f~QcrsM=EK~ZJa%}(%VFju9qTIfdA$dQTo zPq>ReACTY~=g*e7{E(z%7+zDCphj>OL^HZ(zT!8(lwoooZfCg>1W}7Yzm4eW1cVWU zJvu-EwzNLsE;=_&AZHiZy=if%$_n=I7vwHh*FbW(4Dhh&fR0T3#qBk=Rs#7dnP5f= z8JHlD!bmkzvZ?2O0FiP=^P96uqh}di8=c1dU9I5?GhHqFLGP&(*0>xk%jAX)gkj-p zLf}d9A+EBgbd~49Yh@wp6fCj*Thvyc=dq5 z!NT$iiy8uelc^eZN^b%?P20gpg)BSAS0ekXda;^fT8n@N1Kew#$Tbtc@u$YIf9`Iy zKQtFB**w;lKRbtW;F@N^H)ERc#?1Kgv%ZG#C&FV$gG;%oG*N8@SWks}Kwh4Kgq@~6 z40J3|8+O?(z3z;wff$1JC}k{2w+Z%QQst2SRa8ArI0aVU9xP`|NDI8N$?MquD=W+* zKJjB?e4M(rS}Z6YlOp&+gG~}BaGaKlaM%IR?iMlB0kh}1MkHgG&1zN3R>2?G;14-B zW@9{*Wr3xbSGA4I^OZb>@9W^&xV36Tua2Auo!?6yRHd|TQfF^R+nU;V-q@;_cx}e` z3JM6}tg{%)abJ?rwH&eEYpEbXDk7I!(RV?#jw8_2tQg{LWXFGuZ^B2CLt=1w*lBJL z8SjY!uHb-=c@~VE5yo8MhE+u)69_Sl*U;3~Dm$$fq}mX0Z&R3k_iYIog=cDauNPJ`=JQ)aSA*eE%rlaT};QOO*K%Kw!O}KZ{2%t|XKK5Y{$f z;hx4@XJlE06=t=>@;v4ULX(y14X2ubuSb;`KJnx?F-*@v^HB-~p0#}T7qaHRq7h3G z+BE7J4Os1B7Nv8Lj(F|xRS7?`bM*sqd$s%t6lk6?s@3jcBO3%&!y)>CFU#JFDsw=! zv>d?ha)Wc|uwytfyw;`V1RsJ>T^5HZil}~DE6U$c0HGnos;+Bz@gaJP#3Ty}I z4`51ojEQ*5UR&iktBfii^sDMcrxOvwily|7m$lSKvZ4dsX?-tr%j3OWcf|(ZHSb8? zInoSlg$041{iYy2EbZx4zk+rgjdY|}4y|GHjh<9wRKwiX(D#USRtDV8y;mWry);lz z)Hf-hZ^ux8JS!E`JU*Iqn@&=K|htV5~G4pTqj@xD(@~q^z@eBsqBze>Dorh4qGRN>P@G*6OkTQS_ z1zRT$dFqpzS~ZS`s~)@0=x()c*Z0&rJKAiH2>2Bt)%i=m^l%hku zdWWtmwm}4^;M#dqhQ^6@DPoCml^u69AY-Y`@#M{bnp~_>A;+*{PNIBMymUqP zdqcdRIxn5=@a1a?ZSxk)x6gPcM3DlG0^KU!?GphbAOYVdg!_NaV?P46QB`q2B;Yyk zJo|;a^G*k%Jv6MSD`pln*-;H~tTl|bq@Ppn5eI+?9obHV!QXb2>##b@r_}raw*swp zg~;_f=2!G_*y6#!>CHAQ1A>b>3ta2*g7jCM5AvBquUdb+vaJ4S@dR+OOtdOqX{3wc z7Fq&0Po!{ptCZ~x$OiY6FCjAKuF43HP|n)&Tukkj_(FJqk>U6JqS$cM=hP+gHUI$0?>(J3vgW5(I11F#&d3@Ma9u(x=*XOy{jCTGet=?u-Uz78Y zS;m-jCN1QvLB~pb6;Z;lQhSydwk|cCcjvIAGwUtzmJZf>Q|PW;8Dmhi1+O!TRg%P5 z4J>YbuLTmE1$w2V-}#B;#>Oo}hx3?Sqtr4~@R`4>LWAitDWs}Q^#hcvy45{)tPn99 z+Qwoweyb#k$NN=o&4JfgnKriWS6+`UazYN56X6>`4pOl^^HqfOYIG4$@W4Aq$Udf& zA@Q@|HOKc$;v4xx7zMc{{fop3LTB);r(rCT@D)T#(IZC=>e~_?5e(8p)Hua#0#dDY11dR zPQBqn2nmZY&QSm69SZw;EaADOgZ#*+C}_L&4rccX5T|? zq)d+#OP?!HZ2lF`@g}y|*04;CGs(i5C7URlSm!csbP_!5p49U+3>4S!lZ$D{`P{n- z^w|nR;63-I$}k&n+%gExf!quqJ$L@1Sd%Bi7D~p47PY~|T<(Ivu}s^9V#3_rL4f=L zE=sNVXYSjz7P0U}AgBpzegwM;r;I~841lpa`)RdAk?wQ?0H7+V=%tNTTlt6n1IuYr z$2Mh54uCs*1bS|Nm|8E%!Pn~(yyof8kvCH*jn$p=coL&)WQiA~x^O|jY=MB72y{N& z3pZi_b6TL^oS`u^ov^qze1-Yquhq?E?j#Wbb0ZQJ`}MXzvyMp9URbH=@%idXzU0_9 zS<7S34#&-R2hi#lDRwb4_)qv(K%_s@I_y!9R9>Hnx}Lu?l$h?V)&!P`*03aR_}x4J z<7F9=rXg-n0yi$23KWK)r6ts&{AITRXDZzJ6K7i}?^}I-|4S+|mKg$~H!NSU(A`pD zevPBWUEAEfzKm|AO&Cz+rENlDlvi1E%S?RT=?jB;&JB2_D(?>;N?!sDY37sY`Crau7n)F6}>f~5>1|B^Sd zVD?ib^d{1k#wXKnCWps|_NxzjP1$OI;dNcS7QvSY1v8YH1n?PgVTdnmAJnTyNMO2= z?ImJ%En*8Y)w{ae(27JKtnALYFWEb!j~kJ&0S;&1m4i{kaWh^ALDNoE%JuiH{Z!hz za!=j$BjKVLoGi;R9Pn#z39l5=;hy>zX+F%4MwW(<7y3;9VMa&O-?IL*FY?E3B-ZhZ zT0$akh7KNBFP_Q(V*y-!C&H)xeIO1{SaZNYoKFzIv>TdNF9%|LhBX&hRPI1sA%}hb zhmo(i+~n;%U2v_LylH*l&ssmOZ8lc_@FhkyxRc z|M<6T@TVjbijO-UJO#bQ9|OyQQ4wW(VnIXAO(sn6<_f1GfQBWU#86Yb`c!j$d>OOk zz8nuMs*nMvm0i^g4CCJmSiwGb+66Cz{z-|TyQ zwhEpMT1CZfe4K)Dq|gmSByR|~VrmVjwWQ(bC{*KWaGM=f;_70JTE4 z2U5i>;F}ja0x5Zote`BqJ=wh1Y^dOlxwZ8^5qQ8nj^&Y_s(U$Dhkthw5}oAX7wxs3 z0ey_kJhhIth3+(l%$r%$i$VHvvXEe=!-`)Aa62$g%T_~;u^Ycro)XOhwF}CO`GI7p zBEiHbX%{*Xe-kk4jnX)@s)$b!9zuKBjcDGU9><}CFVY}btJod{|G27 zd=u95ThogHW6CVpI-E@VAvHE*xukTUy`h%3S|X5@2;s~kD0>Qzx0LA~6+#||fN7G$ zMOZx3AF#)Y&T7wM!RD+F9BrKow~ z0H#=j5*uQImvM=xTK65HLzT~YgskP$?o-L-Ig$obH;6{o;>ZR$ew26uU$nhES;`0! z!m%^VRo7lnQNGu6o}bf1lxo|Y&5UMEo|rvANhxar;RLwDJ4iHoP(si5S7x8NgbUNN zWF3LY@zI@?gGNY453lcf%?)H-R5l6`0&Dh+y;wxAC#9#rM*McV+%&}J0K^~ zkx8$CSS_TY7#5??D3dQV4s%*`Yuh-1cdaa@S?z%1qsJRbKS$X%2CTw)OKePD*t{6m z1CK|1sq#q;^$R&!wPX4$8iJ$U9UwtX^7^Jm0@~{aOxBB}tEQv!g{Pl%& zx$5iHbIaVdFGkru_Ws_f;(jN83bjDwbW!nly+X}q+C+&0rz`Pe$QAi|+QkZsXGp5Q zk@S)6Y3d9)K4w{%D7RQ?x++K^o}<6EMl3=!QWl`ElnphexFkLSUj)+J^@@D*&~ z<`SS3vvTHfM22ofPI0DeE41e+{C799p6KQ)vq20)>GdmIQmPQ?!xc0H9fXdIL~|X> zD3C2>HlDN9CT=D{ez#)U$|dQC4q{U zi@SI0vTKi-_d?cvCy%+O-n9@er8NQk`A5@22j#A}gRZG6meoJuq~x9XLBSX85EowY z&*a14sOW8#IjB#Z?-azXKPU&aZrH{wvYWy=3697RDPZ@ucy|PwlO1~WIH;8i$IaCk zV?DQ4M+IGo16_~0*44HnAoNBLPn5lmf`kN_C^evG-=rJ+edKsgE-2li0foJgj4k%+ z+2A77R}dBJw?yHvsS7x1D>+}nOUPA!6X*-+z5$lL#U-r-fu1Oz!8YWh4ZOO#b=+nT zjkUQa+qh#jm~Vryg(!du^gJi)B${m7GMYn7TkdEVXMSi}49E@ftQCD;?dxnDRa8N? zVTgcUT4p~t-yS49oe>dbJ9k|~OU=#;4!7_wWUhdlp%IKg;0$esdQ}z;$8O6R9^ibV z%hItMTo_m$_XgnuMlEZqg{yF%9k-Dl?E*4tU%byZ8t_3OxcI(9yoYYDB>LUL?Q%mK z9fHH#tGi(nV{07aZQcV?&kqmha^SOAjfIaUutHc3sNsz9Q9w)%cLU9%@3E^C^SLb77sf(;EHq)%zPK0SJ2HznIV z9G=c2M}G(bo+X7@YdH(971kHTP^S~>*)1zku1M>P+FcemX=yw|kJICE+S^T!O`B4cx=C>7=lRnuhwK*}j4chPhK_-nPDQ)3{Xpl@kKJ*T2C*8Kf(f!TFlIu6 zPqjS_Q>3}`m{6TBdhQtN!DKd`|cViE7?k*Lsc zR@$J$$b#}0!#^3!n{I=}RsV$ZM1ci!6!jI94kEn%b48{&8zvE!UEzAgMDl)DNXKZtfMV0X&&A@aS%a(2W>si2hg&9&1}6Y&Sz)U zl|OpjKY{9=YKYQ}jXFz@{NCxce_ggs9=j#k*Sr)6K*qMCIqKF!L*TlsQ!veh)>2;e z8OrmwdqegL{GW@P~MxlFNzjiqLs7hqF z#P87AxM;9M1G7*4WqYV884Vl|a)seRsCsOAKxMhe-l+3h5^yt;^UXp?SjE0#Oh@h6 z;Rkn**Ovfr=ja(mHY20mLi>PV$;TOaJJo(uhG$SIPTOLmvNin5d0?8nH5_5gcApy- znlCoZ7)hckXnpQ`TGo1iOer(GgL6YMZBsK*l!KP_VQZWGHdx2)D~ze$eGO+mMV{zK z2e6P#pGa^Zo-Elu>v&u@Ewj(Oj!5G4vfYFu4=en&(7@Q_I`McC1{YwJk#r)z%xh)+ zIaB_1BEbi$e5?e>&--?!9_A;8O%AT|gz5zbRXc@oXb`d`>&$f=-?7&v9X{>H(6Za# znq_^DmpanwM&HaT-96UwZ!^fO;}Dl5&@pd@)2uzEz__-E0@VSD)Z-Y9zZ|%~bp|)) z%i(peM;m1P(Qida)Ch%ih8++yd&ie5?CUtOZ$d3_Q5aC zD8kuD=odpO4MZY6=?J<-w3)5rk#lcm@?>1jF=xw88(}Qmo1B-lL!j*$dlR>crG?%~ zsm#Mh(jlJzzy^PaMI;!&H5vj9uO$l@2dl1#)*A8>L}92D0_kBA;p z(2802dTFHQ1;1~P$2c)rkUbh1#=U)ua8Xa}o}L9>#w=`-J^SI>lFwO)NJr3A0$fU# zkw$c+DkZq>7zRbHao`#8-0}WUzVoNWV?xE&02}^WwjK#y`Rpw-taa6$ORC4O9iX6G zed3~!Vd|>9g_LQ_MR;7RMdqW2Gq_rys3LZDkjp4m$N>@O1fugj&aBAN5pgwk>37Zo zj-k1a))hpO$+}c)O*d%x=r36=LOh=bmibL#l*h%WfO2VB&R#6n)Ih~uKK$)vl3Jf= z^AusEzC3*PwjCDEfK6>6CU^8Q7HIfs6kV57I2G$xD0&-RlLyDMW59E9WbuLUrZ`~e zFA-7g6pan>zRa)Qxyirhf~?3xsx@wvPEcD6tF#`H8f(6{bK7G1p?-g%7foyl-V_;T9FQWi#xyLiCClm7VUV$jR-vjmMTA~ zh2XDy2IeVR!F*(*5V1Z}K7CdC22=Cq9WHv}hop+t;}47wBa-j@c z-#MC;3uYNT!O$DhCD&I0uc2s%XLCC9%izz-2^OAKxtMi_7#o^TzdD>0c$ukWli1Wy z4xq0B<*O9>d5GCN@*@YEL+AqzI+4KirUYcHTU_ta24bHAtbKINk!yIs%7L~%Nkd^$ zNF8^3xk-g5Mj!ga)8(gY0!3$z6!v<8)>T0xj}8+8`(rcyc6b$H&fx+lgJg=K7!)tX zF<*`%OjjP$(>cCi-$i~+JMllV_=YQpC-Q?@fb_34fGox>!T3iOkEl9HAdk&2-(M3}c#{Cn z{Ux*G)avHHfhBdiFcaQ&mn?YVMjqm$bPDQ9_4`Y z<#HbRE%mc`VY`G7?PZgm2t3Smr`!$G!qcj(D^JErOmia!f=&_B$aLe~6I-IQypp!T zQl%0{>r9P$tgSKx`_k7hX} zE|nrK7=>WFFq1$wdt}kqDbbtv%fSdSS#x)O6a^r z_%zPQc>%O&i5RvQjUAuEb^qyKoLiE3hnUOQFDtxOw^@10pn5_D*H7NPUF>!PGV*q1 zkdxBdmlRGVEr57e@!AI)5EA$<FPT}F+5l7P;H z($a=82Tj)$mwHW!ndk+a7KLwWj0pZ53eNfH`)=Ga_|!0{6VPm*0{?9dE1Y$z!1kI( zDdY{YbB?7~0=nXb*LqDizN#GV(+B&iN!_RFGuU%bNN<2eCq?0O0lZ+I|8VBj5^hZM zBmyz8yP#DN@ofMgi(>#}abR~Lbz*P@hk)eA*YJYZ>_S?U%ySHB%KMoxYb)42jQoS_ zk^o}iQU8BrvEr(0#aJ&CfGp1cM;4>kcftb5V#8SgS*&z|P|~n0imsUB7@xGq?5)#c z7)-7!q<;juAji6NNb)@eNyh;5%z7j)z!G0lICD`|y;2MRA6d+xKiX`+jiQg;q&`Lc z^B-9pzJ-|n2-!t|%~7>`)z503EHFgE;`u<@w}fEt+M;svP7a6ac}wYb zl&4$V+?MOIbw){Dh5e5#K5`Z*4*iu&`;RPcDZU9A?Ymsp>QPmW zwjwxOibcJVh+-KpjoE#1S5UNNh{&GYJPt=TuJ9*ScNn!<=~8(UHkJ?O^}<9wSLwy~ zG$dweBw=Js-AkHg>`sjh&gSET&wqLQ^*Upqsov7^q1+E+DSvd=Lm>~6(S#vfoSI^flOQs$< zp?a8#H16r~3r;kYCA+N5B^4tyGGPj{s}pBfuPT0C&;7U<@#Vo&Pml$o?*~zy1OLrM zeQui(k{4gj?{+lTGgmT8RFv56FXV1?sEnA+h7E+F>5B*$FP)QvYv$_qx6R@;JQbS5 z386NEm^8xG<~L z2TVuT;{&J-;+3M7K%^}!BWHTYwiNJlZP(o`{z=1gjp zY`>8fd_thZDa?3pm39txNUJeF{HD63z|Y>rza7p0s3dg(4xIZD8@=;HENS=B1u%;( z_(^1~K;M55#X9s=!c5e&q`JJY8><=LKOV1YWmGtO`yKak;zlTl0rO1&C z_qRyj9H%>n_g8AiwW}MnQbL2ke!5$J=Ps9n;w;*tS}h|u zwwApVxSmba67zgwivj}71;7r9pV!{PMq(F~LZj$LLZ$l9+%`B@Ip=Z#W-+z&{zB(n zLY;qrfyhYbz5~M>Kjc^WX4dLrIIBvza&2cP0hlIxflwjxlwM%Y~&&A2*9mA_1rGvaTc;08b?4s0wGW_R2 z4REqWeFoOhCFdS?Tv)MC@)w{*^6McP=Ae_11Tj=bYMqBOGZnXG{0uss6f+lZ;H<{4 z{OF_3dywarmz@xZs)LLf3 z@b%^D)13M88*z5p$@hPjAKc-2CBt-2a#xL~D4B}Ld*Sb)ZqMYE@=JU=iv=BG#zIMM zQdkzbeU4kmxmk=+VQQBv^*VU4Z8T&&cX48s%1^02n&@v^V$hSvL#>Mov8V8w9-mwL z0CG-u27{gXm4A&!9v9slBc%NdoO}`F&*9;C6jGKK`p(ANe-d06x&D=TYO>uI7a~D#F{q1I&akT|Zve>+iYAXmtB{X6kLRiNr0` zA3+@Dz_V3c(0t3fj0|sS;ijEB6cYnY&|5A5IV|DOb!+BV45uI!v9F+-ho~S(QN@{2 zgl1<{wXTuWZTWV?n~DIWxuh0rXgNBW{3v?1=jhgy*JF_?DC8|6TPaf=#S(m6F*6$2 z1XE{`9=>wXUEYFvxbVrgd4RyQ{)(D8ttWIYEjnAxu|(q|J%Tu7f&;At7W%+yjs7Fq zAnPm?p=Ep5ld;#0e`0FRlJae%KeKbarQ8uMk_Xi{Ax5(#npb=E5+j=xm`DHqvaR$og`ZoDwU!+mAPIBI6j9nm#s%7JsV5B5-_k7RIzCg|Fs zPnE|_m@cr@$;4)kD1bTEL%Mde>p6%MfRj{nnH|U-JXqZ6+xf6G9ecdn-1w~wr8g8Q z<;pjpX}Cw~?oCBBU7|$^!sO(QEL|Ykjuh@p9&v?Ml?1QF0&}f>zHVb0D&>E;KLF4f`BFfTSjR6-eG-tqAUpKOH#ClOB&&TX>t%b#Cj^Mf%M{3{%em?^vsA6H2ANL8Kmz&Jw)JC1;Ut zx>;8pbg*{iQNo@VwqQe!h7wAjGB~Q$T4`{Yomm8VTR$KNxcd}+xc|)A29b#0>q5!7P|UZ2Et{W;_t#TkA8n_&aatG1go2NJgS}KVUH}|6~bsQGGZ{Nq4MJ!fi`7&Z)7aiR=26tj6p!#fO!IykK zBqgloaTcKnuKX7z^B=tLD|W{(zEuk0)FNrQ%Ojg;*O=e85booJgw-OsY9}eoKXkE( z)pD2cql=MWq^lr`+tT2jyp9ipv-KWDEb8@QSEf0BfCx!bl7Whx*(lSz*)m%#`Te+} zKgQ}raePHbgs93hjw|zl@HRX&i=-ZzYkX(Iw5?x)CG*El#ZCV4M5V5bDNP?Dc6@x!$#RFp^Y;bw$it@eNtS)F_9V8*ME@&ZD-R zXS*E@-LzC!?k^02v{^_H9ps&@wSO{~e}Qd2J4P}{GD1vJ3f|8B$`V7valZ);K#Ma% z0ci0E!G5-!WhMYE-fS@RndG_ZX|C2gtpuRO;Gkmish;}l2*Z%SY7>hI+8F!&F;Q+^ zW>~qZfm*Yk>b?D@#F*1LSRQawah@<7Abkdt$QQoP(*4odVC)dn)CEuWTZ_xCh0Xtn*vfLji$%(XNU1V`dBiT-_6&l?7<2EP>(i(ZYlq(Kf1B)a<&L4ezss0_)N zb(`~iRX)n{SL2pp_M@wLr>w3J{W^`+_s@6aKHxRZr?k_7Sz{nT#MN2|uyd!k#M6QJ zw4eGjrXpDlqN-|L;e05+2JYheHk1_1BC!{wW`j5eIiC~~Qy@2u<m zZ`#7Tp5M^O+L`M248x0PX%3O3(<-~}HkCxz>Jb1BLm%_5{Yf66Ww^z1;B=gq>* zizbnLtDcO}q<@j9`%$fjU@J}3@=jj}s+P7|?4dDo>^ktRjjj4(RY+;4GWwD?h*#T- z-ff)CAyS&yK637tk{eU_mD22t+lYQEE*BpH(OyvlE0zJ&V#L{&{$}LZUvM`rzl#=^ z9XS*pE^pH=#&0S^-x(ylS^ufUC83RH5K|KdL6P-q!0IdQG(O?r>iXZ@?_dQ7MF+?Z zV0#1TmTLNURB~!kL;$tek@Eh^h08Fcq-n3+WsssH>yd~^J`q)?(tHl%fMPXYOWWGx zmOuQXsEoU9j<#ks@ONZ^q5%zStmB!f5PS=_QFfM$I%iE1RMq^o>VIl6W8g`;&Rc>b zS{pcd2R<$Ea#{8Nkl$l622M$!oS?^?I3j7seOsl}fE)M7_~T3kGY z7YRS&H?*uLEIprT4QS176}U`Es=|x6##H0*-i~2+v7IpMCfSu2;aiayAMp+Bm+N1X zKYDGXLq<}W$eHU5g(9Psew#!>WMFZ;^?jnaD(6=FH1_i8>S=bR3x52~>V*NEUj=op zZ^!KK7{w~57=hXAy1DwZseQn#Z z_~^CiV+)vhM`#&}(iOWK&|rR@Yi0`iD#78(1!W>m<$A1c5>`sLf)B~G^RP3zDYdG@ z(5PWKYv3nN(Mg_5hsta9``3t0j@>QV$UwyklB(-ZX%MJiw?xoZCdQolpB9E&J`62nB|%#chwUPk zhve{5zh>gY#N_JPxb`l(3Z##39@@A$d2D!72t5eldS%^$h`aBYYj<#N5*)E%5c#Y~ z{8M)Ev0iXFz@EJ5-Tx%#(2tD1DHR6WsJn8FD>cGK7;y(ycD(PW}F@QTocm54Bz>bwk$8}tKY!tKn9O2;LIMMuN| zySq;DsA51_)$}@rz+A_1ct6gtozooWh<#UV0hslYM&Rb|7sSSoaXWtWznD)o?9L4e zRHGnn!K)NtJ*0vrZ{R8n=&2bHFGdA*USoEC)DP$d+KPe-#-ol@moH`8!?%maRRjTC zLMcXQ2g7xTd=MJB_Jae477Sx&UtOzPeymj;D%9c7>#PQ@v7C`BrCz>@PFW$jwq(<{ zHa2|p2w4@Go8dWJ1sK;Ma24x(XU{wR(nP$pQOAiuA3uLw>h z@VipI{XHPqjy8It%~S!6H-N+B_*}2p(r=vu5A$cpn}@e0s5#nji#G zPNTjAH=Bh@n*`Pn+e}}?D)fpv{?m@fYS1j3klbMYzH{EEhHv1)79v0`hD@gTrxvgI z-2=Ywa;}a1J}@K*zr{rTTyyM*;QMFCkb1E!k=9%3<+J0H+|R10JT`nVodr! zwHR_T68+Wj>arYnS|)U54p)1ZT2*Vm&lovzt?JGdpcXr{$}TJ*+_%eM%SQC)_w1Op zeteFH;#33F;`n4X#G@Sa&8&MdSf3F15!8Qbal2(SBO1xt7Vi)&$A`X+8Am{wS_V-7dIFUIe z0nE&u^c~YurcDPr+GJ9%wWK@8CGW6;oE250GbPN11w`|21urQA)Q_J|;vZ`ki*(ci zQK~g^yp@!Xv9{${Fj{ot@#Meu>+D4({yNSMKIC(vt=r^uuuJ`H>d4bF(day1rXA^+ z%HEd7@%<{AY?j7d+4~8UNyOiP<{mf3|Is7?P>UB5KiJ?H#+(b^?R94@l${mz2L7qV z`PlSx|J33Uk2_D-ySMTR{SR9CR_CI`-^P_}N4QI@4vCXBMqGY+%v*>y8BZtxwK)ER zV97(K72aukyA=!kL$LAZ|I}i)?zaaqZO?2ELFhxE_=;)wsWRb`p%Lehe`@jCKeZU- z`?E{gC&h=1$VT@3NgJRR|M{r-tNou^912j23xhDJm$#aZ?3-!K4rKYYtF2x1BF)(R z0BZ5`bo(DU_|u_(YVne>EteFfm>J_2^%O1hES}{eqgTKqre}@Ux`-q0VfS^hHaS2o z=GWjTTDFA&sKqQ#W*^edEdSJEBjvYDXs_yjYOx7rRi2{D+N?YxLGv+of15Q-xJQtY zTMoj%lu`@(MyVuaN3N`hi}a({arw14C19!{uj{-m}0C z4q#3m#-iYU)2h|cz$)lY?3XK)c2OnukNns0F72$M$L$9-zBpFkz(@{sG!9oQr=}_E zeC|cHT|TR)*PYNky{&fbvmNUism`9s>m7xg&;>#cqX5!b>LWcij)iS=YoD36&9Zu+ zhMsw;{9mHeX^0w&rPl|>1f;;8q}MJBYr#TEG3hhrNUdE&YSasJ@1Oj`s-^a?Jh28M zH)e2Gy=U|JbvU0yMmv0(6dZMQaP)z+NSm}UsLckH$3@Box;PacxgQ*VXI&+9N%3vq zDZxG}JgRW%ND8?m=nGn$n`7Itay*LSFoj2;ZC?Al!D0*0@3!_HB!Iu5 zO%5VP?P@A>oxWL6OZ~+10$R~&jCr2#t;#R}YB3T(EuQC|<076Qtu_JuiflJ-{y?<8 z2~{7OL4S-vFOQY5cy=JF4vDEDU`p24C$#8{5iyMxC8w-i_ajg9>=_ko$W@GsV9r#9 zk|C?H;1G8*h$R6Mle5hn|7E%#$Oz^tFR!2J=2Cg7|8co)D8L~{ouvJ&zmrK!&n?00 zR&%5L#{vJk*4@zUkv%lv{v}yv(uXZSfr)5TuCvx64xzjO022BUnqN#j7-$njW~`Z- z60jF@voP0*1^neOqoV+XG=8#C%B=gb7#Bfld@t$AL@kk-rlyaAW1b*J0nvLjo9O4> zVtyHqQ|N*&j+^7sKHGZoinfDl4vkVAwDE5W4md&8=q~W6FvA9V`i;zfEzO(KvdwIh zIHpuwse-6Sp>TKxQ0*2(9u2b+g=YH{z`|Q)2?p6En;Tw3Zzn4?wR6{bA1So21wj}* zV0A#OuTEjMgr9DrFvaobBuGESa7d_RXz`0&F+$lwx8(Jr&b)@b4oA0(_?-JnEmC%% z;3$uo-idJIH2#uYVuvuBd9O=wE?)3&lW#~)NIvZ0A!hJrq{<6b?e{?aO3I?81Z7<|)u^~C;naT2AHc%fDz^KhRW`#_ zp{(%R9%NyS@HcY*Y{A}_NaT5N02^xFe%=7ZWZUD>!~ELAmDKJ~g~o4>ht{j?1s%La z!PyLBD|)g80FqeXI0dN1*Na9vQ^I1W zXpPh|tDiDnnMCc4lE({R+bn5||6eWM4uCyhXC!g=DF;X2?MB2zk5!-C{&NPL6fb&( zOl+8dwTQNXHZf`T8`&L3oW>bbQz1m)6U(CR27w>Y4NXDTF;X58LPj7NSJcg6)FKt) zq&hg12&K{wd&#YFBG$OG(PR?BC|J4^95otVCimOkQksl5kdev2$&lHQ`VjfNK^KO% z=Khn>*J9F<;>zC{B=a+GD{1Y`*F}#xM^`@xPnq$`HL_}53LirSyNP42a>=f6woR#mxoseN`5NP~SDlGxB)v?DOdN@)P{%K2uzHECF)T8+)t z>S&(Q@;;;MH2jfyv1GJ0xkBgCpig)Bo9D0Kq({-4Dt}N&^vR-viE**AOY7C!T3m`X z$#YND1|rnEY+8rs>K8+!AS#$rb_tdTmPKA(x0(&KUxYr*8!tQ_fAN% z8vxW|L;F=s;V|SJDS%qMki)#{OR6gz$%39#nwP6dxvcne2X?wsmC*&q=W*y(DfIu; z;;qv(5cEHdLVLW!cTZe4Gu!$7n=|EL(4~b>TqirxtBzKrvO3MTY34V=xa3+}hg9%O zULdr*dh8>2+f0dE)5m_~rQOT|M4q$OVRI>R`v|jY33!!WO}rSZrDDN8xn>Sv)E2Nu zOu_C@e71Kc@{p@Z!5iiRd@6V8-&@sbi9cdoz z(d7ft5ZXC!?Djh(KI%yQxL3A0(;t>5=ok1JM}u%p7A>M zQqHXPXF0U@PE(Hzg~L#|iG-R^f;RW*zGWfzgI#|~EM}k9-t2@hj-7Ruj6FpElq2wW znt0~;erpqYT{`e;8B9sDJ-=H1?YmWYDH~L_Dwzq~7voB&XxZ#!=||ZVd~jBaXw^Hr z1~bbNqEJE>6V~H;#ZNv4J?xhE(K>TFAqY<$gp+ETHCB-kXE_?pqi}~2tXVYr)y=-7 zp!nXs6FdZpNGamh=)!dEh)+kYrl*TzdCuEUV@=kKwIFal%J=4BIhfDkB3Z#CuI<~X zlE(%hdolzGr+OwMCX^A$_)OMHML#^HmtF_KO6et4;p>OKODj2nv*dKptTdC$u&(_! zf`TqVFqbjIgM8U8kJI5_Zmi6cDXEKaGh`6yUGureGej8{plA(0u2ZK4Gs*Ne&PE9W zPdN_o*D{e{WxnUJ%26C^YLt~Q>t3YF^D%8+z_`!><0WUgU?cO(JZ2&z8;j3pt7NoeD^^(AmH*A>0c^3f1i!Cu`}gklWOubTziO6k6#_wB zVT{tO?U_mPM^shvtrX|XDQ&swzD9iq*>TWT-~;`DY(tb62s6cJT%^^LQlcxRPzq@c zs;oRZd^8H(XSS>+CYS1Nm?V3VL8;v9O!eI5{W`m*FucM=7kf-pj}n%Q!g&~~iU+9| zR?pp~gtMz-tzJ%VQpMD&I!=F=Dfx~WAe3(4gj8G}gR^bz4Itjk2%_5L0wRy1{D|D` zbwPcJC-U5~xl{#N%(8&T@$#Q=n77BEf-OUu|JY(>TfO4uiuQCW09!0{)rrLrE?Ry! zegl87(%m*~0APz{%cZ{1|Hl?%=F)=%Z|i15eXtKqunRsy{2yDKo7mD}7WXn8zBL@w zSelqK`J*p3gs03A6q=!g;1yhr8TM98DuR>Ltb?Pt<*t0r1PZZ z4Pc8~fnR%K0cG2lL3I1b?+aKCjL@SM{AL41O{;|bZ%c3tv|FOlP=Ta8fh+cyNn}*VH zBsDoy1y_9M!5n{C#OrfWL10AcuDpIY`=pzh^sIH(?R`$I9=Kw}#?dhz>ks`LpynKK}s?W*WQ zeRz6(g|+j*lEyPCz8gDL7U!hwYrf$yd?(_aJ+#LXFf0?={?Q{(xe*9_>`@|$3jAg6 z?PjJDd_71szckwAYR zCs$=W)^!Zk$vEEzKdi=IR?hbw-D^h03?jDS-|n=f#79i@o%_;rG+aq27GYa-DWCs! zVHYfNVncZpuCXHDRlp1UFqIC`WwcWz!<>OVW{ukGwLf7O?>Eb63aRtg{*`v{>I3go zwSO=bj(>^*-tmzn?B5rUZ1>LpyY+TByLCc-!X>3-P1`7((Ykr2IWI4Mo!d~la&Ux- zAdNa_S>Z1+)W$2{+yZ`QVH%?1sTk*HOq1Lg(Ma22<3+KdNvN`W1Z{lQyK;Gf%MlU+ z9iSs~$zDO8rRqV@j%4Nbr&fqzB50ek5nc}JKllSkg$NakPWN0OHo+#nZ-5J6>bb4=vK7l^_C07$3sxc!-H)4OEkyVFDQGuOxY9fFil`&je8W!|$Zo2=wDKy(qtsgEt!D){U<@Noks1=}7t()}1YjB)wq|@W`YzNX*e}`9-GyXl3 z32=*>A}q=r2MNFcZn3xn4BoST+$Vn&z%Aw-#frtoP_<|5sYJTF!f%=;oKZ05aM`4$ z(>aBK_oQ2v%ZyrOd?o=ExD{xYx1bXYl4BKHT(v>ep5Z=C;#&Z>YkzA7sZ%CxOG|5~ zXn;Bi%$I~tu8?U!>nEznfp*23M1S$RiU|Fy?Ir$FB;waiP)ZV+qq?*Ikq45}5El{X zDs7CqtOO6YOQKM1w?<{FXgG!$&G$1k$~9*0UUYUNW>=qD&pJDzusKVTHSb(nawHqw zP6l2jl*-4z3vR}gI7G*;hD$ltutYO!6S~Ao^}QSJiWMn%LT~V?1vmD=zDy4;UPjI? zaLyB%t*B0JZVHG|H52MJn<2^#^_Z|HD9<5g1-;al-uZBH&CqXF1`W1*6NEuu0lq9PI`}x4!3-!ee3YB&x9M)f zn$HcacDoEPEv!UIua-ZGYGR)(+>q4SwBC(np&%q|`=ZYiH1~Tvgzl^1?X!j6`D^2z zgnJ@7sQDbN1Rv>qY?4~KAxqvu&p9-3L4T%gmIXr_AzfxeZtXPAi5U%1wBu?@@!!P04d<$JY(4sX; z6nS}9W*K70jw{RrG_KNv90b%{-zU_aKOn_&3B1aZ%lV3#Fwp7un&du*(l9Y5>qng5B11GSY#v&|N+-v-vPAtcr0Zk+E65yoo zuyk^_YA&)2%v<&2qo-2<^Ts8|FkxoeP`R0xSYt#M!bhiAv3@&_8EE1lwd`?tR`^2)mm8B->*^OpDyHAV zmFNb1W@Js57B`h-AG)VZ8I-<(T9740H`j8=fP(Flxz=*SZ(QrA{~IhYlHwscb9Q3p z1~m-Bhyr8pT1pTEiEKA^nlM-kK6;l!%LQRot3!mx-^I5(;~03bhNHZoHl5ieV$8?Iyg(ZiDOn_J1OBg4O z5a;@?OW7LCn=u6^UOV^Fyv&whf>9`h?QjoL2xWI5j(4pywhH}MJo9E@ArWBE z^Gf!1$A07SPhaZ3;X0jn&K~^!RiS?$XA}{bcnv6WvrWn>4EagyAX%wSdxt&vcFg3f!E>j#OFXk&cpc7S$1OSy*Iq7&hVK0ZEZGaek#{KBn zU;g($&#mF)>T<2~c_B!m&D%*#&GScfaKHSNkQ{3|K_U^Y`vJ?9mWswVw8p&|mAEPG z-ZZx(*y1=$IVg#g1xi0jDFL#ewdyaF9Td1GC>BYv8gv6rp2O zFI4c+!F?cPbDFptSctV-Xqi7!-~Nw7i&BpK?(W$MowQ)@mB7gLpr|pCV~DCkcaeENGh0`M*m61e$R654dlE3NBHKXUL{8Q5xO8Yy z4q2~dy)zhG(EZO6i$^}_A_2#VlN8*-jrk@B;km?p+dkQ6;25y!`8;>^$ z&?m663r`y+)OYtKhClcvZ%KV?h29Y?kPA{1gs~KlCO4HYj}ly1K{*6_u=HmpH@<)F zyuxhBw!L0#8dsOJ4)08AX8)SC6*jTpWzDWrAP$J-Xh%)3d|JrPWn)?~B)1w!E4)_y zR5pd{MmA%$HuJq6vtJ{fy|;Wb$u-TG};0+RqOx=Ll5)O}j;ZeYi|sf0Z0(bo?3X|0H4x>7CP;MMXXboR zK3s-$BCnNY`LdfhMU%Mbc4zCT26q;CUR!i;3dTJzF}kD(*RBVTULE_*XAjv9FN+cR z#Lq0IO7eLPm#E1?x06@P`KlczMHb*0qO3Qlr;s@KPfXb04rl}~Pg^yXTI6g>ml@6O6g4cayIgbiM2Z_qPV4?7KLJb8Gt{wPE(S{m)M5 z_dtR~1Ou5E=NQco8Qi}LTnuq{8c|P7K-YyAd*A~S6A*EOb%_;KcN!!}^&^)yg5Uot zKl6>tpv?McS+BduZXPPwOVF}jJdE(5=aZ~;SBpWUFe=c&(dnJ%m^0`QU7!I4y%;!I zbu=kr%RFMnTiG;1JntsZ3wU(>@4W9A;fk#!0YM&Zk!*-FJ?@u?OhAf+|Sb$QUbd+nccAh1DwEpo{3~ zf7lQ})tnb?(417%z-4Ms!f48X?{+zod3F)*6rAm$ur}?UB6Xl+rXSnp-u9JUIjRn1 zRQREKe(D%Esz$G4zZpW9R+%)DB)#B$!!AFBK%R#R7s=D)j?*k9BwlS+1)h{t8A@sITC-y7m%zX-7PS4Pu0h>$14?>PBg@^;r3W% zqXXpPm3QQy5)f^sW12H};n*IFtzA1c0mVlC{luUa-cu|n^m!zQgwdw3vBVi#cuSqb z&zl?ZmAv!h0W?RZIb3-n<*ZttS<`qEniB|D?+cc=vrn7bNHeZ}eHj8wwM5SM7Czmd zFZ$4{1hx(p2nPH_0CcL4MD_|XsIz`ezDg`Nd~ZihAI1ZP`Y|gz7~swpkaf2%xyA0gg1 zBM4={YGhp+1f75M`}BQ@KUUUU-IZ}Oc1p^^RKl%spt2+z8RYnfe~0{7pV0bD=PY%J zZsc10fXnDpUe>btcC{C31H|dH?Z&A$9F^uyJQfgmR$2p`I@t0~*8IbCSZVHGHxsZ0 z*4rbaP7tDjdnY`-7+e;AwH=oHNe7g}-Mb=fC=zsZh)hAjRTKXh>Nm}f}S3*b!*+WT9Gdr&wt52Fyd4$uv9`;@8O%>faUiif-L;7wNaZP?}tu z)}vM9_O>^din4_fO#NE;Q5=AI=z4lvFhQ^Dz?OL3<_6Fs>TTxNi*Xrg4B5F5R%fen zZE!)P$L;p-_;G#rG-O(l{BPy_fHeEm^6`cB3AObL$H5Zxp1r25P{BM0KZ~PG^FP8u zu7(mRJopr6lbF7g)gF&+@3LF*w@{Bp{$OOr{gLp!q`#)TRvYY945RNjrJcXmo7MLth19_T7LdY@-Z69tY&V^~0=cujU4ii#-I z_|@%as&GrW*s~ zL>04~8cb&zG5ir{V|_wLM5_`SG}e=ql3#i#(=_zqsb{Wk8A3)Dyqag^;HlcOGxU6| zqj;@m`P7F0Lf=sGN6>#=Z7G$h|N25CbFZGz;M9hsYI+b@q_vrIW5 zNU76HOMY6D<*?|PN;ZkuA$EK_f3CxG%EiPr;58JrkA7pabc+z$uuW?*^bsJ|={S>} ze^?;>o`*Wr7!sM=u9w_ltc`~>FOWP~PpPpM5mF4Jl|ApfabfGGx?7-Ps zd4yeYtdMFu(+!ioS>@bTSVeYiM#c7PHaO!iWHd3EQ08aSfeEyIiH-82asa%&YdME2 z^?^xv#)r*<42Zv*b zNf^4T*d}WU!}hCESrUJ&LCLhwI?t~@8;+>2^vYcaR8X^{>|*Ar-sc&x=&R8~bvOG1 z^|Z?HE%9wApi&zc7|kC7UaF_DkUnF?H<*XQ4@UV(abNR5#0%FVEDq`Erb7~iw7yfNXN&cjchv{L^Zq3MLRe*65d&4XNT*M=Fxjv znxG-CVf>ie`_-35fsglO1HC06eja-s&E%9Txsi||pDORY4>Jh-Dce+XGjZ~acZqHSsU)sax2_}S z0*9)A`+as_P=uY_a@|D6*h+|?8r#%U=Yeaiic3gR(YXZDGXY0bceSyBN{cf0O9s}g z#kBzwkg%`@+LF*~S-SahgQ`%~EmHCRgBZ3(yFu#^bMZ;I0cLxN%`?{}glDrR7-l&( zrC`}#nivRnw6U@~aJRJjhx$&avP%Bit#=s|ur&pYUyY z^rOgW81JOHNF@EfKuAntHNKW4IaG!*wCZSEJtvaVS>?QD`Z4jyM~KL&Te7ZVC|^+?wP{bOdgG z^|YpaWuXXa)x~y1+0J&h>#fdi(Tpegc9#p-c;@x> zZ^-~!pqF%Gj(9*p9j2gQuAVPb%M_d6kzE=?v%uV>`JTK9m!b^cR6-Vw3#qKk! zOVzFoX~C|k5A>UP^zosy?zYoZYV)dKwz9j;?1P&(5p|Ulh9V zRjt2zdjHwQ;E$l_W@wZegP7OoM(CKeikC1`TuVh*P05~Rbc#Q7YqM?yEsuBU>Cb4@LMk^26ia^ zXBR63TiDt7_psn`tXi=RLAJ9#_)!F&G9NN$G98yJCe_tkR~av3_X-^q5-5#ZbV2~n z{sP#=i?;eLR7&^UN(-U@ySTdN9BbGs3X#&W*__PNGf6zBM*?6MtD#4SA%><~*#!wR z752CELysa^hZleY?Ba1qk+Zwm>prG$GJstilw>9r>}1(jcBe+xz>l$rPCFcCOH3R7ux~s;#@s8ku=q@JWtXZ zy#pvEEzvA(Z1XGwmsO{lrM5fU6eXOfQ_W{`i+l1V+_%EJ9304AIi0y4HmFSZ97;%h zO%4Jh4{XF$Yr|Qh;9`P_;1v4=8Nu#_RLk^(!R3hZ-_{_LmrP;G64!40GqCBP{vPOq z-Yf_rUS@$}NrIh%Qgg||&8g9kRVjt#k#=*AG5V>awy6mD^;tGZ;Q9XCKU7!a#Vv7f z*U=6AdWT^}kw#?$TOMIDRmsm&3$(`NL2=ddA5^coh{806U%5;CuUc4=X~&jJSfW@q zNW%5~G$HS0ghK$8qTJvb@$>x_Ge5IL1F%ZfkN#?>=vR@~m^=0?$A+}r=DAyTo?%*Y z6APv$XTQnw$>At)h54o$UI1$WYYv*4^13d!(X^l;XCu1yKed+^u8}ZS@HDv6GWI(GH$K~-F8f7`t{ih7cSoH zXfi&_|FjKg8Gos7kJtjXl8m;)Ji!Zci)HFzP%wY)#J7?>>cIlXBE7aY$)0lnvOVi_ z7-E;IAwcO)>TTez0VZI8CgINUZJ{8;&kxAHApqxXq5!aXMDjf+_|f{Ay+^DeP{B`)^iy;cjDvkS#M~MBl_kAuEIT;k}H8UXYTdbCXs*vVwmc5S>>Rb6f z_LK^`VvH657I0@QVz1-kXr(P^U}gMSTU-1zignG()tn}A3pmM z&)~Zp6kEt7xwka>`IxRL1;r|0_K$XA#Z}+Pn#w-lR%*rd>K?N8>+^@i)M1EG++X{F(ko{8`xlYEHoL zpK$~JKaT%DVFm<%+!zt22#O#5fA@U;Oa61^f7Sl~#r*&0WBdpF&&bTq@;}-?BMZZS z+5dl<{IyiJC8ZMi@3_L7vvbh>M-K$uzbwYt{)P_}^1pZb zkCFafR)b3_>nq92tNdMUW@zJN`rmZ2qAG&_S_cRL^534TznvLqAsKmjSusf&6;Y+X ziXd|Ga-x475tT$0WF&hN} z|Mdf`q9XIx0g8$7ueS~d^IwnQUnR)DMiZ7+mel(D5>Pf)R%W)pwUTmw%~DogN%LRN z6Y3vrg$0Er{%#E7?C4@D=7Qr21*Ie^{?|YRynF;+a)Pp=f1i;5@3_b0Gz7{jf=Yio zO#kTfUwZnhMpRDZpY{JJ3CoL!iu_&tkGiEHQ2EPK`o}E2{xILaIujF=m6VYbRsOp| z`(K*;4boq={|cXfsQOUA1lzzlD2b7UYx{z#qEJH5hGDpP#ZLheSps?|CDL;&Zwspqq!(|wX8sG}d=Z#%K-tg*ItcD^&*+lnGr$I4H zy5m`?fdw?2N7lPOevK6O9*()Ll-tHDZQsrpYKA_6+@87|N3#>QSaBJWY4k+Tr7^^gyQjf2xgmKA|Gy6&k z*~+De=$|mI2jJfkacYsJWxF5iQ*!CsFbE>!+O|j0P__~wNj z{$2iOWMX7vW&9ugKQ{LNvj6`S5fS`*)h|s2@Nd2}v;E;?O1#rYD-sSdsf2@)u2EH9 zSK?Ju5Z|PCr7ZIDg*joT%=QF7i;@~q=d4S`1wyL?LD%AbCNs6{1%4P>p#}Z$K9oM_ zg2^vot(CHrRp|yEZhkD&nx4#;obW4bW6rrb)hY@E8H3eQ=yW33c3Wq^a$ra!>irNB z0rTb}Mp{r4TU->M!g;Jkil(>mMq|r^>*vH0Ax#f$Ts}=UAKRjF<Zs`ha!9hGf+mkLV<$^WmAdEIf+S`zMMRIevp6vt z=uKQ9k#^?Y=K(&Lqqd?G&hueK*k8Yoq=u`WI80&mZ!SDZev4Q*>+3?1+NEq_gEV>`k*S(%3p>H2jX6&O}RKbF1Ld+Z48_rP7r=!dw2 zvIb0Qsp-f}i)65LwZ*9@OFA=0(vD)m^H|iApvCxk-*sNaus+IcE3%2|Idj^BqU9;O zcP*BI&Mi8CNADBL49KUpl|k33iXD(+S#wQHWzKu*Z#8T0khCKi>V%qU)sWAaxFWH* zB(hUBXS7IzpS44tc`%JDjQY@QtrYvyA0FpnU`g5lB|d6wSY}N@E^{JL{)7Hq+EFIF zkldbU13oi%nIm8cr6CunIQPfH)?utwkt};lqnX36MV2-S!#kT!G3-&<;aB!Y9OzDM z)CTS2(B#h{t$ikUCOY+AY}yeV-X^$1`L#!!7Hce9+vPCG27xOYWgHR={)0N(fM7xX zJLzrnF=-#1_k&Df@L`y@UltM>+?hB$liYZh4HW9Ma=FurY2qxjssBdvdMY< zuH!BAWotIFtgh!TF$1tTogi~CvC4Pvhn4bi3(Q)tUr7lQ}-z#6S@JA(ATfteU#~-7$-e@{Ifpz;| zVmMU_IelrtPed)Yb_+tQG!jpk*<`1-?-;szc~b(6*tab5ApWYweSO=wnK#!`aoc0sjmY^r?1`P{ZgWJJC2yfPrNPD-f{8ahI?Oq z@6gdX#%gn8T;u@dO)ITyrY^UXtC-Y}eM#cy41Ys2m_ss|3_!sr6*Y-kkCNw#I&_>b zDSJftTjW5uf{Nff2pEd8b4%(wfKNjEGQB3@=UY@b-s9?AT=HLNDelo{;J!;hSxYG< z;EuK+Kia%~V8t2);1`DASw3_`GZm%`cI9chZMhgKn3rc8;QZjr6c0rqHFdogD_%)I zv3;GPV=A;D*pR|y-aR(r1@h?fg~5Z@GCOq_r=7dt7p)1bk}>QOQ5e&x%9@jXgSjHt z+@;s6Px!>3NGbvKjEXEJUT+q|nVt-li9PN_#Uf3_yXeKDs*|bpWTC{&jo%>NS-GXF z3v+Kh^U%fUC|H&=t!*nZc^b8i4!KeJhD>qept;Fn`48 z&g=dge9J%_z{GmUa~`XH+$M?Nz?pid(SsKTU_KvEOn6;J{163$v->`zUTGil%>-dX zE+&mmN%a{OA&&GR=h&9)EuN^OpY<3+zl^vDxw-Q~^YQq%SlaH$!sG{%^9I-CCe3}` zi1HVhAdv0TP4ys6G`ye2o-46i4XPmdR0cizWN)ass`yLgEg*!~EWqnewwN^c;7rC# z880x<#u>tagr)Nu&jOUYP?R5cV%y6578M=e%%t2##Nx9q$2$^2{k~%|Q&Q=8*(@_I zWG6Og_e1kDz|Si>!0D8>MXoS^ zgx$g>Eb6PzPBKEQlp_#3N>BcQ4gQelqO?@VMn%7_r*n0k4=+CTbB?UYXZa(ahyF@| zO*;C5aUyp{>WbX19jLCeQlo^SXkA0E?M-;i8-YME@oxQ=QHs%TQdjKa6GOeZ@+Xxb zQj?%4y(2W)PVUJE@z`q-TW}X7Xm@CYGzua53+}e&M)Ukdqp?t18%rQ|CaSHF?{?m+ z@aEnQN-g0p_l2E{I7bWG+M}!+Oz3GA6NWrGK;ewv%3V7)w!d&Qpiz;9uO;kAM8h&1 zbcQDdX(3p26mu!u_fW<&Fn>cg=|C=9G%TV&7XLC;hdnGAWX#R!9y3N$-J7imJ;*1K zCZL6g%JjnK?#}kj+gA|{GK@gkECzWGL5^V(E>H|Q#h*6t4cw16{JNk=tl0MO5_Xuo z9Pr+xSj1!2uhUlpZ%ahAu5+K2-$mWV-fwKJB}mQ&-TJlOC;-LvskxOqn0!6E9C2cS z*J?qK?tH9$iy%_PiehomqzTO1`w0ak^L}a$mYqnQ`!x+!i zFj~eO2IDUB7-fU`zLWsdN6O%@`}O!;mC8qNX37K6STH34!^~c!aL}+^tRusu^UJUe z8NmnAtRU)(mdF%yqY`ODRI1fgq@E+b>hR;2{}z=*u7BPPd4eVwRBnpfTNgjr5f%~x zfNP-nmmP~q7jP0R!h1@Y%@SXEQx0qzM`kxnF$+gL$DC>}QmK!}!)Ca$X=D+8@r~lf zW*e`EbRQN(2a+u$J|%yiT<;>)W}yZYVsRz#x=Mo_t*vaXe^Ufy#OT;l@GlrzpdG5c zh!4(qkA>`E#14Quos#rPKnMNEa;jFK@*^ek8;kuG*0cf0E}jpvB)+{n4I%1`?~1hO zA~086Gl-+01WSzuD`h(=#tAbH{RZEf9UJMz%6It*1i7sJo={Wxux!;?7DWPCw{WmB zZ++lM)T@gYS_{dnv)dSz?}=)n^Y^T6)Zt7XKyiG7D-V+Pt5B|^SAA=2nHY$*D^LS- zmpFa02}ckZ`|1!EJL05pPd*ee4jBHWqpqxs$vlgy0^YGBS}U7eRz4Clx%8+vW8~;8 z!WQSt-2zHdgiYIVrDoUMHUNQO5fHahz$ytR&Mk{?UtH~j=P?^|3VOrzSfXbtFUTd% zX=20>dDdtbS;-=T<^`)GC{^3*2EfN_b5Vuzu#W>sr78@0Vrv{bq0uWfP~`5aA5?Im zhjxSmq&1#gL}(BWzO}=vmfnIXNvD({S19q9RmuJ+Bo2ApbZUFyye@+1rPGIEaoZAe zRcvPyD>)-N2}M)uADs@b1`$WZa3@Y0b7b0d?#Dpg#-(4-cJhBEdzwwO8Ni-`imoj#-i%w9R@6pwWf+( zjPKe=s}3Dw7JFi8D7Sk;zd{{T&R9NNDq6N`!wfs55m^WIYhiaxCPV$T5Xk;Msitnr zPzF|DeO`ZL-I$$nUrQ72#E5SqH;$S>;&W|?e6l950_$#m6(QG3)Q}f8>m;XambS8-&9H-zdl_>gR@?J$v*djA_TPHEI?!vAc+|?v2CbY8 z#6T?2E@JsYO(1S%jwYzidCS{)IrKt7hn}TOL?o!5ZF7Omb(UVRjuf-V-D_G9R@v!|#a&*bpPUvXMF59a>0P z{K&#p!7q5hUl|00WkFW=&9h4D7*hsq)tA~ zzPH)M9TdGuh#`9a^yU z$0jec;~Ve~`6v&Pc@6T$pEbV=MaUoU$v&mW;n9WG%UURk4EeQJj|+dI_r62gWFMat z{@Ug~0nOhzP2_c9MG1^0VgJuFCV)~pqFTU10P#h(JMsN67~PGdgN$cbP_j51y7WhU z!HcOpDho*0f|7XPhJ)XZRBKqwK>Np--N*D1xZn0w{g8skC1>Htsd z(@}3|cb)=jvpOB2_DD|C%d1;2DRkEim!*ST+syTUf8ZBF;IL!U45$^KTDmzrE{_vk zi@X9yJ0DWMm#YVzj1dY~lju=Sp1)&*-CmDN!$&eZN_Yxlp5l53D+%*cg+;7P%fpFx zEut_Sa37CMN#Ks0^5DV$9=xqkacj`Lf3VU%b?zsgwoyoMw`_oHd`s)=FlT?+G2Po* zzSJkD=6QuRKNc9T2_%uq%0PPLIkZ1dA*&p^C3O0}tZB{3c1KjcCZ%Dg=Mh~b!|XTG ztp?QsxpsUG4Xew@Q`TeU^R6QfF!tcjxTNQ0UA~};yhb%Xfy2p}lq()+6t2iF+;WHG zHo6>X~T_0tt4topInVKzTcJx7|O#}yt zd99E15NU}rgK_8RueaI)?@V3#4}0-uX`_R6Q`zV0IM*rB?O1NLun`a1y%p>}bkd^< z>#Sc-XZN$g8?5opWFJS96_NzEzK&c>clZ^3rGzYr1KA9>Ad}&`UFOB`mkue z_!DwihZKk;{|6iQv?NT^CQ!6(+qP}nwr$(CZQHipZ`-zQd;atJ?w}$va#dyIuBV{? zOsZ&(B)T5z%(Q%(WZ{(q?zvCka@ZM`LlYWFDZZS;-7VS+$wH3{Z zb@w4V6o)TFdPrSxk?j>{W;jFb`T3fX3fSCt9q0%~3hkEqT7W!5^kb75p-1H9<;7s- zrj>&#Tm(db0#rMPhKQ#D{ITsidJF4sTM*d`nMa?B>m<9?u=7gd$L-!_TImP z)9@trz2+YACZ0tKW#`x4K`kC$Y$*03m6kh9Y5g^W0aitrnA2stNvb+JdhS84-_ zr!-iP3>uDg@f)p8+9Lmihyzh@BNohAGIWZ%ogP!)UXyF%2wa-jgT)(RgKdP0W%QB> z$Oz3@+u>)pfRVfRq!(bEh3Rg9cEHxSg(DIMe_Xg$sSRJ)xAekBGb3PD;3x`#K|;%i zC$uBN(W}EWpi54zcO7vFZ8vW^VI*F~T^cuVBFIqorcOt5;t8f;4_I4+>2LP!EI7bt z-;+PDrBX}d`DzO6mXBI8SrD{5wyUGwRfC!jAG)|J(Aemz9qzws@5-!@q8jn*=SG3u zlWt?1pkjZ&D2P_Uz0-R(!-$m6iiAdz%c-6fT9U3--_t9ix03RN`p6@EgHa5Z{AHK>p)#B5CrF`!PG9slko_a;No?Hb$**Bzy70=r9VH{&Y8Vx?0M zkhV|7-;Ab!r?`y{8dE+>>=U;dKmHvT7~-}6cp96}XOWsRvh>(Xa~H{@#$oDOemK0@ zP#|zv8`875d*VbokL;IpUnE}qdo5Z=9M|{u-pv^}Z`C1P2?3JqFRn zCaQ#&t2x(oa3Aw2n+}c(j!b1K?k;l+l-_eMKu}j>o!J*{o65%?=CM(E>M1jzk_F?rpq#f!enOxo`u3a5gV!kHV7o% z@SM4ak3DLBt(E-|=pLIE(-f200P~W}M-dTzZ-&gf{s~Ey)a?3H4%H`UKyr0RDpVcGt znUM2tmU_1w2?x2K)sIS_mAF#fvW4YR;_xGP$gl@dW(2fa#&n7eMV5Hwg&HP~{) z3s2Li{e=e71dR%i)75O!MK;GvijgNyxnAgZQJDjR64ecWQ_zMdPOcb|UZ*K;Z7JvL z&p=o>{vi+4u7ah%XF&(jQ28s0k zxp_+~FlR1!6V_chFkSxk<_bm7vE9KZg7m1X^iZ@9^;;~2@YrPzZY zaCt=c49&*=mmk=_w3ekW?FvT&A658m8v2dQbHAOk5v>HTyCUa|q2WRH_8++dvao`l z)$h&b8_q#0b{if`02}GXDyZz}&OmNazOe_YtGS3v6I^(kjtcN}^FRg{xaaEbMo{14 zJi1#sFuzY=-HDCAHUztVPuC~LRJ7 z;j`_S05q-(!HGo9079sNcEp{hw)5XRD;?Wa;j8iB{tu-TXn`EL#k>U5O2quf@IxV1 zXk%CJuS+hFw6i1!O`PFUgTf8EQd1M*{QfIOV*KHX zM5xN}gms^Oh)@lvF&+X7h||Cm-zcofFoqlxtra-pu+J9=Cf zbhW?BaWz(%)uCV8`{yjj3kGP@&~1SQ*If>$o9b^Q!VX~Unf zaq4aux}yYjX{TwV3-5O91)0st)iF$g)|PtrOiv<)qZJplk+@pdaxzQr*T4lRno-Wa zy*F&70?*WOfn~@x@ee&cyeBch2B7lB2z)ZjXb&>q)Q#PxZ`Xme@sGwCebS)rLKGgB zlpeh3%>`|deP?gs`pa{Cy2NIHw?M9DoCjyg95|Q}`}h3C)H>*ie4KR#JE#Vn%=>&grtIWx;HlbBM zoivR{Nr-Pf%O?1O2FtQ>LG3NLnO9zor@n!-wha~lc4rD1uyN`axt#VSu?UAyd6%3T zPZ?SW^MI>wW4l)`YD5>Yt_E57VQ&a8rU4E$`va50P}kI7LhB@6c*|TGkz3mp2Ycpr z{r4Xl{KuS&Gx-qKTNWDl%eh^AM9v1JD7TU2j)nm0UTc&qGTeszI<904? z^&|gLe?o&XY`?N4lvhp-I(SRni<_Z=rldeE;-fh~7aMOwLy^nlvgMgApet;VJd?Tr zc$HbhFw3hb0W=P4o*e1*m_LSl3=@%c8IgcTFGS?}%*2HUPXTXv4EUV~3pp0lf0T7J zNR5I3aSbBN8#qg=X*9|!IP$VrBSQ=$u_zNg{RET}rt<&#Y~`EBlFaSbW@DL@mHCsj zk`5!TPZQu?pXwX(DB%p>f>LN`3@60JF;MxLBTtdo!1-tG7R<_6S>27VIdejVHWjt7 z%_2upkIWMwD4P`EH9kix6}mOP=nL%tT6mzjT#_be%FJl`8sVut$Vk$Q?xOTaB1Lh# zwl8{){G$Eo$3dK4>}I9s6ywC<*vdiR#6 zVn*m-3oV@u-9T$a_nv(zb*%D|Gn=LU$wkU+H@Pnvt5H7)bWIC4O$n8A-m9^y|pvXL~Xf5cECyJeW|eNFz(+7m!a9_kJR4OXDL)d zUC?VD7(`NKgWyXGW z_Gmo`SwQ|&XxLPLS_(Z7Foe|m?s-ZQg0GjzHxkH5 z*jIy?SxhivK<&mO;KJvnH82F%yZo%t_=EyICP8MQ&5G4QQM&)F4xt;ywv@Doq(Q6! z!GwaAh?;P|Ft-=_iJfQCyl3fzJTGT(n@#*2cOPsf`$pXw_Nf4A%ade!wKiMB*FShG zhry;5TJl}aB42Rs47FvYmKjwXmg6RrL*F6(-l4Io37bjP(%DnoxtcfRCN0vC=>(mi z#+5fRh&*xidJmA1^x|Y4aUBuk`PocTldUBg7IVMqzQrm^*yx`ytmP5SH0kYivTZlVNNH7F7pCx&Cl?7r^#KgY ztkO3Vk6cIf2@f~*EP@F}3?Idjxk;<#iaX6yc3k-Uljz&rE&WseSP~VbO$p#$jF2HUJYoSthuiu=_AsMBgeGRsM|zPrOYwjiLQqJLcR>e&NwY%K=Q{%Ly6W zFUP$=jL5!2fJv+QZi*nYvxYhb>n6&d)Zh@gR3<;cbd|<_A+wo>tP!i+Z*(k@Bp3Yz zsq^wbR!Yf8Cc&mZ#5zRtPP9B}>)+{?9NUg@&&X@FAHtE16EX`B-ZwxWpMLT;eerD0!5j#Rrcazn!1RgAu_Cumea{R2 zKSQ>q(A{(E3l0nXhX()g_jhpbNuWB& z^ue>A;oY^u7IhV3YPQ&9-xHaQlYbg%5t0wNh3^4jCZbj^2N{o#CyV%6g7KT``xvcM#|*h)j#ad zDJqqy1sMn{p7(BT4lu9pIKx|Zn8~Aq1Q=!%DVO~(-}aaNn#bC4!Vs6z%{v`GAINcE z(a9_l>?9cEm=o^Jc&x#^f2ZdgfZuVWV9r&_ZQtm|k4FTI>9?Wq)NTd$`t;`!k{{VM zbYEq$g{+@sVn;ET87AV}jxQpsC|jrhV(A%v9?7e@z`!ABkYGcX?qy0z)B-8gM2+{! z*{-L7O~zgB38w=m-38g>NHMBZ!{%7iKF4xq!E?-q32E#X%rXghJ6j^PDDbV5pAI92d&sOym zspvhRj*x(jxONY!DE z>D#Nr!6cmJ)UXa8i=2K37#Kf;D4%U>RL#H@?2o0DRSPXj|4L=V(6q!f0STsDah_9h z{O;{`IcFp=O0BrC0A#LghwO~avswFH#AI{U&#zt!b&u7z$_Z z>@*?i53jVCJGJAECr@0Jd#~r?bsFEEsLEN2wGasN`!q1=b*7NfJ8y|JtdnOjw1{#F z*+~E!Q`qops~G+c9gR|_l=?k$A_65K!1KXBD%w~MCY$sJTWCy-StNdO@njLeq1yi5c?U|N8ap)<_4*z zuZoCPW*Gm890}we4FH}5@uPZ;EN8Y%VZ0Ty1HhtUJ5oES5t??seXeWI zU*}GRyPLM~IRC|ec>4gPDe!*y`mgvT$xaX&bicS?)r!MUt zl7#_UQ)MjXhp{U0i+2cz$OF&|{#-Cn%Gw1#9(bO~G|yV%u36Z}TESmnKF}xBm@uF7 zO+*x$*}s|lZr{ryL2=g&asyL9{vSjVZHIyz(5u!ob)Aj<7utx@R9ra@Nq1bMHG_Ta zxkHmy6h2r}%9~Byj-{F8=VXT%JMSC@fhsAW-`=Ny_r2Z?5n}iICHOH(tQ=$Ywgql= zG)$ITU1P~LEe{JeDwB#lXc&W1oOfjLKUTO{F3Ixm!b`D#R?%f-hvZWBEoT53dZ`A& z8~4M&w^tcGHbt`dFKa4&k+dBKS)aDk*A|^BOYZB3uF??mDHl%cUbb##OOSq{x)0<+=d}X#VqE-Jz`Rp$(=!%k zq#p~>`_z4RShDOOs+s}I3K4HlIIu-8$2CNA8LA;CEU9AZb zW)IN=vP7>f6o+x_ZJi3>YkJ1OctRokr0SFX{Fj%;1xODN1Y2M$oE5isgg=119V9iR zA-+o~xi~a|Tl0g)ulp@nSMrcH^1U2Qd)YviQCE?D)8>#H$!H+3VJ27KMwQl?L)ryD zNqojPsvYBj28W1RXc(=HVW=N(4(T9Jsm1BEUk?e0iZi?WGW8K4)kcHzA)hD&?=|x) zC^K7{0H%Oz8tD#W!th6HstF5s@5Z}`>GHGya*e>T&HB|18rB7X?kC0BK(tc}J~=0` zq#zdSvXyklj)O+)Aeba$B&o>wQqZ+9lqx}#`BM)Z_2B7|R}M5`fSr>Sd_Ce&eifBt z2ojTPd8`0%Lt^m3aZ0y0I>$qRh(2mhhLf3%1&XJjkVE9Dfj_?hSS3>DlPh#zlr zvpBH2fs0AqX--!@u3?i$O_-2QcBi+~!#G3XbvUl@5qb89Vz$L40!9R^==%U0(9a+0 z+sflb5qAf3b2&*`xMnCzlh%dY5rL!%mM;r%y@i6$JDpe;iw~VLXn!Twtx8xPV0R8i zBVVboVK2XJ!jr@xB|Jf}fN9IWGj)B5Qk>BQt4a(L zZkbOsBeZ!rQBf+7HCDqYvCT(wen29;Y{50hrQ~^U+r`05R)(qlQ?7NzsoK`?kKhH< z6PlZh?1uy_GSSsdgPs^Ph4-(=yAqu41_0bJ=f%2;C_6he_}W@IpYqqy$X5!Bpkt`6j$k>fJN*mc`|%#AvU2<5AzsueX}2`VW!Is-s!Y(}zq00xrc zK=Cic7up;v%M zRXj|Nk>|m170ZiY3={pcv^|QN4vavZano0DZBSA;0N?I|V$c3LBK8M5H)xNVSVmJS z<4-_DMWhyf>1O4xS3J1++J~Tcs?|it->^lMenRm_1)V$yXBZT#^-8SL4c6E+ry`zZ z#)(ShP^U7$<#b0yZ!s((#-hj6J2CPlN0lphQ^&R9{;J8QKk`VjYACe0j zFl#itVHJC8x%}skit@4QJw z)XVR|CykuSk(Ek!%jN4$pzw%#Hv%K5U=ELBc=G$;N&0eLf|vObK9LS^3_tWuzj5RJ zj)Y@b}+!GK$Bv|VZ3Z6;KZ?em=(rc!ls#lT#_2k&d0Hae026IJyy+{V zA&f^>RIkNcF2^V&dk|ZOFaSpW>MDvBo%+aGzU-h72o)4&^#zl0)muB=Mqa<459%u4 zNppUsXSfBEW9*DGYDt|;Kp-P);R7hU?+OX;YSeD)nWW)Fu@|gkeo``!p7QQX+}_YB zfs8DVj=tUQz1$aN_5n{sl4NnE8lH26e(?wZppsWDi8n7Z_b1~VP6^bcegR`% zFgBl{G-#YHEIK2eNokH#l>57!bFj}OZu5ATn?VOkJm(78YR9h&&3w=ECR{hXnznPx}`=*aH%6n!wq zu1&2G1(u3?uKDnN0nl;j)iG9{+cerQD)MBf&!rKDyVL*%%|6xufnr2509{aJOS{U7 zXRn2UadSH)dk$q%0K&u(Y(>_g1e=f2#kw-P)moOb37xv8N6Dm4IPnyBJEd}YdEwIN z=>_n^`=Z&)2p%Co0M?w?HSWGU6N4Q*`6k{8VBgI;(OM6GJgr4a)!YxT&SNVHArI^O zj9T}X3H%>vL`^0rWk6$Rjs@Ku|E=vdZiB(X@7E@ykc2bq;EnC z+4L5b?+B=FhJ1_;3onRkM-vpV*^(f)@GAhxWtfGgQfIZIsmn- znfAvm?RpKRy@=QPa?`R|=d$cdv?NZP=9tzEHPr# z#P_+>=fW~RMNWS~V^9fdIOG@-FQ+X6=9x2kFhYp;|$bvbRbO?i)0av zpr#a`Z6Opa(LhmaH|-vj%P}4^tzdhTj~4RHuOr5atUm>tB=%V_ zyzXj{8qGXfr2K~l|Is3r_KYpMtJ@P=0SWt9lTqj%J@#B$4^rkOz1mcJ7inKn&*(;JC8*=$xc$A>>Ka_OLao`BlZm9>ERfAdt zr3SF;1|@2zE4hs#n7V7ga;>w18r-<~QOW_^@v5$L=4NA~Snux2M2t6!W=m!ebbfB2 z22$USNStW#i3|l-LtCM!9);8#3iG-#`SueE=f#(d%f0L^IqBm5~f7G-n^(>Gjk&DWpTWhPXh?ryqJ3* zyT+63+!b7Twg1jd@&#^e9ICko+m&0Q8BZ(nAlSAWQZa1_P!4yW;B&7=^}#b5eTRuT z6MheU6ex|WqTP_fJZ=3d;Xsz-czOyHq_XNjRIDDu8hPW8to&6ban^r5SX^W=O^xhD zfnQ~L9fPSLa@I$^%V3Kl+;U-cR09o*-BT;W+ zExuOhHee>_43J~44}HIv!#_7Y{H(-D@($t0b4`S!Zwnu{udQ0ZIo1hUzdqwjR+ws< zmwv(cESkblaxLeF35d*}plRb3hO>}rMIwH@%7dR3sswfBu1}&{SbR^YlD9_lD@|v) zwr_@PR-(+FcI66sl0ycOJDR4fPL*AkLl*~&B#+bnY(e3kQ6`m*+5=fL!XjpprC*l- zfM=yC*@Z5nK}Kr?(a-n|Hq+&?5OG-ED7^mk@bXZ+tJE|bXwb=jWzd`EF5ntk!5wHx z?DSi*G#PQ__g#A}riPp()v|N#{3=5X=6+LCI+=4r{(5XU!*;c1W_&!5TMtmK%dIC* z`EE7WD>Cvx-WXlJ{G>{Hr3lY}`ymRanjpq+!bn@Y5fnB50sjVTtxf8A!8#27q#?3t zH(N^Z@DOJ^Suq~BMoN_DU2=BOYgE1Z`w7ROY+XQS_tMo15$jen(C1_Vs(RW9~8C+8+;>|;?OcWb_fJu>K6wI@Q%9R`K6vYoIC!_bR-iB48I33ro z2X&q7$7VX*Ei}*tl;nU6_b+|o@26x6o#dnZhX()ABKG2Eq#XMZ;bSSq^+0!XH9Spj zItr)do&Ouyk8t1i_X~0~Fwsb4jA~v@CG_gw+ZQ`+GXtGzTic}a7vCSS)c znO(mKA1cZOr72d4(kB9-xH>-vd<*XI6`{@&=2hr?|vnbJH_;AgU}c>1hVQR=+V ziZ3OgrJ%8C;8ynrhzMP~XqJaQcwHp+H?#${iElB1JFcF%3w1|dRA0L&_1G2_xPGSI zD_t#3*SOa!!5o908cN7n@A*z9OioP@e?WNm zJD&9cD0cBoY=}Rj!aRZh>E6vyv9=}kj}TcM-1=IQOY7dih;Hem>uF(mqaiYOaURk^ zL~r*F=|AEAz4iKDqDy2!K{|pIUOT2#!6dbP=Pz5$o%J=klY%U=eCH+I?hxaTNooYX zh4z<~wt}F@fzH2!MY!^qumK4`wXu@61!tfFh%mhvUbsGXTg~<|^tM2pJOl9A?6&d{ z`oO$r)QOGpNYyCu@z9WZd*V~NW3`-+-KO+mQ7o*AEnl(TdH=nMaM{lVMh0(7(eY-GfIms z?2SOWi^A02093F_hZ88QVpgY^=tpNy&ysPR)*2bY&?#v!*r=fNG3 z)mP8-H<2GbUFL);bj5N*FCip4+!mf#vPT^=zbtEhkjJ^cc}*k`@J$+heauw%ZoC_- zG2P28`Je{GsmhTHru277oVurEakTmCMR?rrWnr`^ z${0()Jlf>nWt;40l6Gt_u`rVdLSoN9D}yhz_~}*tw@X(ph|>{;dE!$vBAs%)cAQ<> zi7sqZvHV>QIn{|d)K1jRP?YvQpe?eKfgRSmR##L3Fi@$%DuJENSN3MSNjl81U@@Vz zIuzO)Z+C)^VM0nupwqWRD~o{EjWnk*@VJ#kKtm5@>TXLf&$7+HAB{EirT!lp{6~u@ z`kNyv$Y#JrfDRx-`|~m$?=ObVi+!|)CnT9rqf{bK8tV{ZBQ$>>JNrU(J?6gzpR+hQ zrTnm~7j})@S@E)Xra$R`2WSlWn;Z)%^s}|o^Rf8@xB^qTUdlMB!cG&<+1TpAqrXdw zE9MC_RjWz{meZ7=qco&CZncCg5}K24yGCf{XGS}{85pOI4v5$!z#&3li^`#R?aQ7Q zV*fh$nId9*7aZ?*UdCrjP0FA^0_RDjP2+6=$Be``$lYiA`99ifkM|kId#%+50MYFt zr{Kh8aK04pVhVn-=XH`lU z`wI$jzvuy$k^sb~0@}Iz0svb;q`xJH_wVkvNd|_$cS_0$@Gd9K38B7mDSV({RF7i8 zcZXHJLPsPw|41&U^9q(m#_gYC?RO_&ZrOQ557-9!R8%*iUl51(*RAH>F0K+rp;}bE zaljCTI1Ngb=+@f1D`uLgK&pk0_u|!Q!NRsD*6FvqUNvWokF+lkq%wAyK~E%Cg{L$1 zHMQ-2WI^%u?-Jq;kbHaiL-||KKT!&4FOH=>awPHJeeq!R(IJ{Lpqz@dvyiyVtqrPL z1lvy{ICHY43$o;rfL3+_{cAx{G?7h&$l^!kyk!U)g9joagbwRZefaAEO@06 z`iHEtM2eK*hNm%DiX%yteO1gIfa4ZXM$%ASZvh>(7$Ds}+E>c*h^)CJ$_Di`o+@8T zU9VHfOQ>|@dST(Dl;S+Inb`aw!yC~Fg<5lUSVFhKuGtk1iTHr2@|(o(IeGgU~1XKXGHof@Y}s z;X7d*i3BE{41+U~ZT;1aXm0|oxjn=As@od020v_7=|5{SJx^P8EAg~m-^i(}>JI

5cE;z3_Y>CUTz1c(l6zyAGW$K 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 )gBQ)Yv@vvRK9;>zW&YGcCtV>CS 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 diff --git src/test/java/org/apache/hadoop/hbase/TestKeyValue.java src/test/java/org/apache/hadoop/hbase/TestKeyValue.java index fae6902..1d024e2 100644 --- src/test/java/org/apache/hadoop/hbase/TestKeyValue.java +++ src/test/java/org/apache/hadoop/hbase/TestKeyValue.java @@ -131,12 +131,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/catalog/TestMetaUpdate.java src/test/java/org/apache/hadoop/hbase/catalog/TestMetaUpdate.java new file mode 100644 index 0000000..2b1197c --- /dev/null +++ src/test/java/org/apache/hadoop/hbase/catalog/TestMetaUpdate.java @@ -0,0 +1,371 @@ +/** + * 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.catalog; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import junit.framework.Assert; +import junit.framework.AssertionFailedError; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.hadoop.conf.Configuration; +import org.apache.hadoop.fs.FileSystem; +import org.apache.hadoop.fs.FileUtil; +import org.apache.hadoop.fs.FsShell; +import org.apache.hadoop.fs.Path; +import org.apache.hadoop.hbase.*; +import org.apache.hadoop.hbase.client.*; +import org.apache.hadoop.hbase.master.HMaster; +import org.apache.hadoop.hbase.master.MasterFileSystem; +import org.apache.hadoop.hbase.migration.HRegionInfo090x2; +import org.apache.hadoop.hbase.util.Bytes; +import org.apache.hadoop.hbase.util.FSUtils; +import org.apache.hadoop.hbase.util.Writables; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.experimental.categories.Category; + +import static junit.framework.Assert.assertEquals; + +/** + * Test migration that removes HTableDescriptor from HRegionInfo moving the + * meta version from {@link org.apache.hadoop.hbase.HConstants#META_VERSION} + * to {@link org.apache.hadoop.hbase.HConstants#META_VERSION2}. + */ +@Category(MediumTests.class) +public class TestMetaUpdate { + static final Log LOG = LogFactory.getLog(TestMetaUpdate.class); + private final static HBaseTestingUtility TEST_UTIL = new MigrateTestUtil(); + private final static String TESTTABLE = "t1"; + private final static int ROWCOUNT = 1000; + + public static class MigrateTestUtil extends HBaseTestingUtility { + @Override + public Path createRootDir() throws IOException { + return null; + } + } + + @BeforeClass + public static void startCluster() throws Exception { + // Start up our mini cluster on top of an 0.90 root.dir that has data from + // a 0.90 hbase run -- it has a table with 100 rows in it -- and see if + // we can migrate from 0.90. + TEST_UTIL.startMiniZKCluster(); + TEST_UTIL.startMiniDFSCluster(1); + Path testdir = TEST_UTIL.getDataTestDir("TestMetaUpdate"); + // Untar our test dir. + File untar = untar(new File(testdir.toString())); + // Now copy the untar up into hdfs so when we start hbase, we'll run from it. + Configuration conf = TEST_UTIL.getConfiguration(); + FsShell shell = new FsShell(conf); + FileSystem fs = FileSystem.get(conf); + // Minihbase roots itself in user home directory up in minidfs. + Path homedir = fs.getHomeDirectory(); + doFsCommand(shell, + new String[]{"-put", untar.toURI().toString(), homedir.toString()}); + // See whats in minihdfs. + doFsCommand(shell, new String[]{"-lsr", "/"}); + Path hbaseRootdir = new Path(fs.makeQualified(homedir), "hbase"); + conf.set(HConstants.HBASE_DIR, hbaseRootdir.toString()); + + TEST_UTIL.startMiniHBaseCluster(1, 3); + + // Assert we are running against the copied-up filesystem. The copied-up + // rootdir should have had a table named 'TestTable' in it. Assert it + // present. + + + HTable t = new HTable(TEST_UTIL.getConfiguration(), TESTTABLE); + ResultScanner scanner = t.getScanner(new Scan()); + int count = 0; + while (scanner.next() != null) { + count++; + } + + Assert.assertEquals(ROWCOUNT, count); + scanner.close(); + t.close(); + } + + private static File untar(final File testdir) throws IOException { + // Find the src data under src/test/data + final String datafile = "hbase-2600-root.dir"; + String srcTarFile = + System.getProperty("project.build.testSourceDirectory", "src/test") + + File.separator + "data" + File.separator + datafile + ".tgz"; + File homedir = new File(testdir.toString()); + File tgtUntarDir = new File(homedir, datafile); + if (tgtUntarDir.exists()) { + if (!FileUtil.fullyDelete(tgtUntarDir)) { + throw new IOException("Failed delete of " + tgtUntarDir.toString()); + } + } + LOG.info("Untarring " + srcTarFile + " into " + homedir.toString()); + FileUtil.unTar(new File(srcTarFile), homedir); + Assert.assertTrue(tgtUntarDir.exists()); + return tgtUntarDir; + } + + private static void doFsCommand(final FsShell shell, final String[] args) + throws Exception { + // Run the 'put' command. + int errcode = shell.run(args); + if (errcode != 0) throw new IOException("Failed put; errcode=" + errcode); + } + + /** + * @throws java.lang.Exception shutdownminicluster throws exception + */ + @AfterClass + public static void tearDownAfterClass() throws Exception { + TEST_UTIL.shutdownMiniCluster(); + } + + /** + * This test assumes a master crash/failure after the meta and root update but + * before the filesystem version is updated. + * + * @throws Exception + */ + @Test + public void testMasterCrashWithoutVersionUpdate() throws Exception { + + HMaster master = TEST_UTIL.getHBaseCluster().getMaster(); + MasterFileSystem masterFileSystem = master.getMasterFileSystem(); + //Simulate an old version + FSUtils.setVersion(masterFileSystem.getFileSystem(), + masterFileSystem.getRootDir(), + HConstants.FILE_SYSTEM_VERSION_INT - 1, + 10); + MetaMigratev2 metaMigratev2 = new MetaMigratev2(master); + + // There are no new migrations so we shouldn't have found any + List htds = metaMigratev2.updateAndOnlineRoot(); + assertEquals(0, htds.size()); + + htds = metaMigratev2.updateAndOnlineMeta(); + assertEquals(0, htds.size()); + + String versionStr = FSUtils.getVersion(masterFileSystem.getFileSystem(), + masterFileSystem.getRootDir()); + assertEquals(HConstants.FILE_SYSTEM_VERSION, versionStr); + MetaReader.fullScanMetaAndPrint(master.getCatalogTracker()); + } + + + /** + * This test assumes a master crash/failure in the middle of a meta ugprade + * before the filesystem version is updated. + * + * @throws Exception + */ + @Test + public void testMasterCrashWhileEditingMeta() throws Exception { + HMaster master = TEST_UTIL.getHBaseCluster().getMaster(); + Configuration configuration = master.getConfiguration(); + MasterFileSystem masterFileSystem = master.getMasterFileSystem(); + + //Simulate an old version + FSUtils.setVersion(masterFileSystem.getFileSystem(), + masterFileSystem.getRootDir(), + HConstants.FILE_SYSTEM_VERSION_INT - 1, + 10); + + //Remove the last couple entries to simulate an old table. + HTable mTable = new HTable(configuration, HConstants.META_TABLE_NAME); + MetaReader.fullScanMetaAndPrint(master.getCatalogTracker()); + + String lastRow = "t1!,r941,1329264314014.1f87047e8ed7504c7dd439ebc732e633."; + byte[] lastRowBytes = Bytes.toBytes(lastRow); + Delete delete = new Delete(lastRowBytes); + MetaEditor.deleteMetaTable(master.getCatalogTracker(), delete); + + lastRow = "t1\",,1329264314014.c15ddd3b8e8504a4228357d5dc8d243e."; + lastRowBytes = Bytes.toBytes(lastRow); + delete = new Delete(lastRowBytes); + MetaEditor.deleteMetaTable(master.getCatalogTracker(), delete); + + byte[] tableName = Bytes.toBytes("t1"); + byte[] startRow = Bytes.toBytes("r941"); + byte[] endRow = Bytes.toBytes("r971"); + + HRegionInfo090x2 hri = new HRegionInfo090x2(tableName, + startRow, + endRow, + false); + Put p1 = new Put(hri.getRegionName()); + p1.add(HConstants.CATALOG_FAMILY, + HConstants.REGIONINFO_QUALIFIER, + Writables.getBytes(hri)); + MetaEditor.putToMetaTable(master.getCatalogTracker(), p1); + + hri = new HRegionInfo090x2(tableName, + endRow, + HConstants.EMPTY_BYTE_ARRAY, + false); + Put p2 = new Put(hri.getRegionName()); + p2.add(HConstants.CATALOG_FAMILY, + HConstants.REGIONINFO_QUALIFIER, + Writables.getBytes(hri)); + MetaEditor.putToMetaTable(master.getCatalogTracker(), p2); + MetaMigratev2 metaMigratev2 = new MetaMigratev2(master); + + + // There are no new migrations so we shouldn't have found any + List htds = metaMigratev2.updateAndOnlineRoot(); + assertEquals(0, htds.size()); + + htds = metaMigratev2.updateAndOnlineMeta(); + assertEquals(2, htds.size()); + + String versionStr = FSUtils.getVersion(masterFileSystem.getFileSystem(), + masterFileSystem.getRootDir()); + assertEquals(HConstants.FILE_SYSTEM_VERSION, versionStr); + + MetaReader.fullScanMetaAndPrint(master.getCatalogTracker()); + } + + + /** + * @param c + * @param htd + * @param family + * @param numRegions + * @return + * @throws IOException + * @deprecated Just for testing migration of meta from 0.90 to 0.92... will be + * removed thereafter + */ + public int createMultiRegionsWithLegacyHRI(final Configuration c, + final HTableDescriptor htd, + final byte[] family, + int numRegions) + throws IOException { + if (numRegions < 3) throw new IOException("Must create at least 3 regions"); + byte[] startKey = Bytes.toBytes("aaaaa"); + byte[] endKey = Bytes.toBytes("zzzzz"); + byte[][] splitKeys = Bytes.split(startKey, endKey, numRegions - 3); + byte[][] regionStartKeys = new byte[splitKeys.length + 1][]; + for (int i = 0; i < splitKeys.length; i++) { + regionStartKeys[i + 1] = splitKeys[i]; + } + regionStartKeys[0] = HConstants.EMPTY_BYTE_ARRAY; + return createMultiRegionsWithLegacyHRI(c, htd, family, regionStartKeys); + } + + /** + * @param c + * @param htd + * @param columnFamily + * @param startKeys + * @return + * @throws IOException + * @deprecated Just for testing migration of meta from 0.92 to 0.92v2... + * will be removed thereafter + */ + public int createMultiRegionsWithLegacyHRI(final Configuration c, + final HTableDescriptor htd, + final byte[] columnFamily, + byte[][] startKeys) + throws IOException { + Arrays.sort(startKeys, Bytes.BYTES_COMPARATOR); + HTable meta = new HTable(c, HConstants.META_TABLE_NAME); + if (!htd.hasFamily(columnFamily)) { + HColumnDescriptor hcd = new HColumnDescriptor(columnFamily); + htd.addFamily(hcd); + } + List newRegions + = new ArrayList(startKeys.length); + int count = 0; + for (int i = 0; i < startKeys.length; i++) { + int j = (i + 1) % startKeys.length; + HRegionInfo090x2 hri = new HRegionInfo090x2(htd.getName(), + startKeys[i], startKeys[j]); + Put put = new Put(hri.getRegionName()); + put.setWriteToWAL(false); + put.add(HConstants.CATALOG_FAMILY, HConstants.REGIONINFO_QUALIFIER, + Writables.getBytes(hri)); + meta.put(put); + LOG.info("createMultiRegions: PUT inserted " + hri.toString()); + + newRegions.add(hri); + count++; + } + meta.close(); + return count; + } + + int createMultiRegionsWithNewHRI(final Configuration c, + final HTableDescriptor htd, + final byte[] family, + int numRegions) throws IOException { + if (numRegions < 3) throw new IOException("Must create at least 3 regions"); + byte[] startKey = Bytes.toBytes("aaaaa"); + byte[] endKey = Bytes.toBytes("zzzzz"); + byte[][] splitKeys = Bytes.split(startKey, endKey, numRegions - 3); + byte[][] regionStartKeys = new byte[splitKeys.length + 1][]; + for (int i = 0; i < splitKeys.length; i++) { + regionStartKeys[i + 1] = splitKeys[i]; + } + regionStartKeys[0] = HConstants.EMPTY_BYTE_ARRAY; + return createMultiRegionsWithNewHRI(c, htd, family, regionStartKeys); + } + + int createMultiRegionsWithNewHRI(final Configuration c, final HTableDescriptor htd, + final byte[] columnFamily, byte[][] endKeys) + throws IOException { + Arrays.sort(endKeys, Bytes.BYTES_COMPARATOR); + HTable meta = new HTable(c, HConstants.META_TABLE_NAME); + if (!htd.hasFamily(columnFamily)) { + HColumnDescriptor hcd = new HColumnDescriptor(columnFamily); + htd.addFamily(hcd); + } + List newRegions + = new ArrayList(endKeys.length); + int count = 0; + for (int i = 0; i < endKeys.length; i++) { + int j = (i + 1) % endKeys.length; + HRegionInfo hri = new HRegionInfo(htd.getName(), + endKeys[i], endKeys[j]); + Put put = new Put(hri.getRegionName()); + put.setWriteToWAL(false); + put.add(HConstants.CATALOG_FAMILY, HConstants.REGIONINFO_QUALIFIER, + Writables.getBytes(hri)); + meta.put(put); + LOG.info("createMultiRegions: PUT inserted " + hri.toString()); + + newRegions.add(hri); + count++; + } + meta.close(); + return count; + } + + @org.junit.Rule + public org.apache.hadoop.hbase.ResourceCheckerJUnitRule cu = + new org.apache.hadoop.hbase.ResourceCheckerJUnitRule(); +} \ No newline at end of file diff --git src/test/java/org/apache/hadoop/hbase/client/TestFromClientSide.java src/test/java/org/apache/hadoop/hbase/client/TestFromClientSide.java index f7430ee..727891b 100644 --- src/test/java/org/apache/hadoop/hbase/client/TestFromClientSide.java +++ src/test/java/org/apache/hadoop/hbase/client/TestFromClientSide.java @@ -4037,56 +4037,6 @@ public class TestFromClientSide { } } - @Test - public void testGetClosestRowBefore() throws IOException { - final byte [] tableAname = Bytes.toBytes("testGetClosestRowBefore"); - final byte [] row = Bytes.toBytes("row"); - - - byte[] firstRow = Bytes.toBytes("ro"); - byte[] beforeFirstRow = Bytes.toBytes("rn"); - byte[] beforeSecondRow = Bytes.toBytes("rov"); - - HTable table = TEST_UTIL.createTable(tableAname, - new byte [][] {HConstants.CATALOG_FAMILY, Bytes.toBytes("info2")}); - Put put = new Put(firstRow); - Put put2 = new Put(row); - byte[] zero = new byte[]{0}; - byte[] one = new byte[]{1}; - - put.add(HConstants.CATALOG_FAMILY, null, zero); - put2.add(HConstants.CATALOG_FAMILY, null, one); - - table.put(put); - table.put(put2); - - Result result = null; - - // Test before first that null is returned - result = table.getRowOrBefore(beforeFirstRow, HConstants.CATALOG_FAMILY); - assertTrue(result == null); - - // Test at first that first is returned - result = table.getRowOrBefore(firstRow, HConstants.CATALOG_FAMILY); - assertTrue(result.containsColumn(HConstants.CATALOG_FAMILY, null)); - assertTrue(Bytes.equals(result.getValue(HConstants.CATALOG_FAMILY, null), zero)); - - // Test in between first and second that first is returned - result = table.getRowOrBefore(beforeSecondRow, HConstants.CATALOG_FAMILY); - assertTrue(result.containsColumn(HConstants.CATALOG_FAMILY, null)); - assertTrue(Bytes.equals(result.getValue(HConstants.CATALOG_FAMILY, null), zero)); - - // Test at second make sure second is returned - result = table.getRowOrBefore(row, HConstants.CATALOG_FAMILY); - assertTrue(result.containsColumn(HConstants.CATALOG_FAMILY, null)); - assertTrue(Bytes.equals(result.getValue(HConstants.CATALOG_FAMILY, null), one)); - - // Test after second, make sure second is returned - result = table.getRowOrBefore(Bytes.add(row,one), HConstants.CATALOG_FAMILY); - assertTrue(result.containsColumn(HConstants.CATALOG_FAMILY, null)); - assertTrue(Bytes.equals(result.getValue(HConstants.CATALOG_FAMILY, null), one)); - } - /** * For HBASE-2156 * @throws Exception diff --git src/test/java/org/apache/hadoop/hbase/client/TestMetaMigrationRemovingHTD.java src/test/java/org/apache/hadoop/hbase/client/TestMetaMigrationRemovingHTD.java deleted file mode 100644 index d1c15af..0000000 --- src/test/java/org/apache/hadoop/hbase/client/TestMetaMigrationRemovingHTD.java +++ /dev/null @@ -1,363 +0,0 @@ -/** - * 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.client; - -import static org.junit.Assert.*; - -import java.io.File; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Set; - -import junit.framework.Assert; -import junit.framework.AssertionFailedError; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.apache.hadoop.conf.Configuration; -import org.apache.hadoop.fs.FileSystem; -import org.apache.hadoop.fs.FileUtil; -import org.apache.hadoop.fs.FsShell; -import org.apache.hadoop.fs.Path; -import org.apache.hadoop.hbase.*; -import org.apache.hadoop.hbase.catalog.CatalogTracker; -import org.apache.hadoop.hbase.catalog.MetaMigrationRemovingHTD; -import org.apache.hadoop.hbase.catalog.MetaReader; -import org.apache.hadoop.hbase.migration.HRegionInfo090x; -import org.apache.hadoop.hbase.util.Bytes; -import org.apache.hadoop.hbase.util.Writables; -import org.junit.AfterClass; -import org.junit.BeforeClass; -import org.junit.Test; -import org.junit.experimental.categories.Category; - -/** - * Test migration that removes HTableDescriptor from HRegionInfo moving the - * meta version from no version to {@link MetaReader#META_VERSION}. - */ -@Category(MediumTests.class) -public class TestMetaMigrationRemovingHTD { - static final Log LOG = LogFactory.getLog(TestMetaMigrationRemovingHTD.class); - private final static HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility(); - private final static String TESTTABLE = "TestTable"; - private final static int ROWCOUNT = 100; - - @BeforeClass - public static void setUpBeforeClass() throws Exception { - // Start up our mini cluster on top of an 0.90 root.dir that has data from - // a 0.90 hbase run -- it has a table with 100 rows in it -- and see if - // we can migrate from 0.90. - TEST_UTIL.startMiniZKCluster(); - TEST_UTIL.startMiniDFSCluster(1); - Path testdir = TEST_UTIL.getDataTestDir("TestMetaMigrationRemovingHTD"); - // Untar our test dir. - File untar = untar(new File(testdir.toString())); - // Now copy the untar up into hdfs so when we start hbase, we'll run from it. - Configuration conf = TEST_UTIL.getConfiguration(); - FsShell shell = new FsShell(conf); - FileSystem fs = FileSystem.get(conf); - // find where hbase will root itself, so we can copy filesystem there - Path hbaseRootDir = TEST_UTIL.getDefaultRootDirPath(); - doFsCommand(shell, - new String [] {"-put", untar.toURI().toString(), hbaseRootDir.toString()}); - // See whats in minihdfs. - doFsCommand(shell, new String [] {"-lsr", "/"}); - TEST_UTIL.startMiniHBaseCluster(1, 1); - // Assert we are running against the copied-up filesystem. The copied-up - // rootdir should have had a table named 'TestTable' in it. Assert it - // present. - HTable t = new HTable(TEST_UTIL.getConfiguration(), TESTTABLE); - ResultScanner scanner = t.getScanner(new Scan()); - int count = 0; - while (scanner.next() != null) { - count++; - } - // Assert that we find all 100 rows that are in the data we loaded. If - // so then we must have migrated it from 0.90 to 0.92. - Assert.assertEquals(ROWCOUNT, count); - scanner.close(); - t.close(); - } - - private static File untar(final File testdir) throws IOException { - // Find the src data under src/test/data - final String datafile = "hbase-4388-root.dir"; - String srcTarFile = - System.getProperty("project.build.testSourceDirectory", "src/test") + - File.separator + "data" + File.separator + datafile + ".tgz"; - File homedir = new File(testdir.toString()); - File tgtUntarDir = new File(homedir, datafile); - if (tgtUntarDir.exists()) { - if (!FileUtil.fullyDelete(tgtUntarDir)) { - throw new IOException("Failed delete of " + tgtUntarDir.toString()); - } - } - LOG.info("Untarring " + srcTarFile + " into " + homedir.toString()); - FileUtil.unTar(new File(srcTarFile), homedir); - Assert.assertTrue(tgtUntarDir.exists()); - return tgtUntarDir; - } - - private static void doFsCommand(final FsShell shell, final String [] args) - throws Exception { - // Run the 'put' command. - int errcode = shell.run(args); - if (errcode != 0) throw new IOException("Failed put; errcode=" + errcode); - } - - /** - * @throws java.lang.Exception - */ - @AfterClass - public static void tearDownAfterClass() throws Exception { - TEST_UTIL.shutdownMiniCluster(); - } - - @Test - public void testMetaUpdatedFlagInROOT() throws Exception { - boolean metaUpdated = MetaMigrationRemovingHTD. - isMetaHRIUpdated(TEST_UTIL.getMiniHBaseCluster().getMaster()); - assertEquals(true, metaUpdated); - } - - @Test - public void testMetaMigration() throws Exception { - LOG.info("Starting testMetaWithLegacyHRI"); - final byte [] FAMILY = Bytes.toBytes("family"); - HTableDescriptor htd = new HTableDescriptor("testMetaMigration"); - HColumnDescriptor hcd = new HColumnDescriptor(FAMILY); - htd.addFamily(hcd); - Configuration conf = TEST_UTIL.getConfiguration(); - createMultiRegionsWithLegacyHRI(conf, htd, FAMILY, - new byte[][]{ - HConstants.EMPTY_START_ROW, - Bytes.toBytes("region_a"), - Bytes.toBytes("region_b")}); - CatalogTracker ct = - TEST_UTIL.getMiniHBaseCluster().getMaster().getCatalogTracker(); - // Erase the current version of root meta for this test. - undoVersionInMeta(); - MetaReader.fullScanMetaAndPrint(ct); - LOG.info("Meta Print completed.testUpdatesOnMetaWithLegacyHRI"); - - Set htds = - MetaMigrationRemovingHTD.updateMetaWithNewRegionInfo( - TEST_UTIL.getHBaseCluster().getMaster()); - MetaReader.fullScanMetaAndPrint(ct); - // Should be one entry only and it should be for the table we just added. - assertEquals(1, htds.size()); - assertTrue(htds.contains(htd)); - // Assert that the flag in ROOT is updated to reflect the correct status - boolean metaUpdated = - MetaMigrationRemovingHTD.isMetaHRIUpdated( - TEST_UTIL.getMiniHBaseCluster().getMaster()); - assertEquals(true, metaUpdated); - } - - /** - * This test assumes a master crash/failure during the meta migration process - * and attempts to continue the meta migration process when a new master takes over. - * When a master dies during the meta migration we will have some rows of - * META.CatalogFamily updated with new HRI, (i.e HRI with out HTD) and some - * still hanging with legacy HRI. (i.e HRI with HTD). When the backup master/ or - * fresh start of master attempts the migration it will encouter some rows of META - * already updated with new HRI and some still legacy. This test will simulate this - * scenario and validates that the migration process can safely skip the updated - * rows and migrate any pending rows at startup. - * @throws Exception - */ - @Test - public void testMasterCrashDuringMetaMigration() throws Exception { - final byte[] FAMILY = Bytes.toBytes("family"); - HTableDescriptor htd = new HTableDescriptor("testMasterCrashDuringMetaMigration"); - HColumnDescriptor hcd = new HColumnDescriptor(FAMILY); - htd.addFamily(hcd); - Configuration conf = TEST_UTIL.getConfiguration(); - // Create 10 New regions. - createMultiRegionsWithNewHRI(conf, htd, FAMILY, 10); - // Create 10 Legacy regions. - createMultiRegionsWithLegacyHRI(conf, htd, FAMILY, 10); - CatalogTracker ct = - TEST_UTIL.getMiniHBaseCluster().getMaster().getCatalogTracker(); - // Erase the current version of root meta for this test. - undoVersionInMeta(); - MetaMigrationRemovingHTD.updateRootWithMetaMigrationStatus(ct); - //MetaReader.fullScanMetaAndPrint(ct); - LOG.info("Meta Print completed.testUpdatesOnMetaWithLegacyHRI"); - - Set htds = - MetaMigrationRemovingHTD.updateMetaWithNewRegionInfo( - TEST_UTIL.getHBaseCluster().getMaster()); - assertEquals(1, htds.size()); - assertTrue(htds.contains(htd)); - // Assert that the flag in ROOT is updated to reflect the correct status - boolean metaUpdated = MetaMigrationRemovingHTD. - isMetaHRIUpdated(TEST_UTIL.getMiniHBaseCluster().getMaster()); - assertEquals(true, metaUpdated); - LOG.info("END testMetaWithLegacyHRI"); - } - - private void undoVersionInMeta() throws IOException { - Delete d = new Delete(HRegionInfo.ROOT_REGIONINFO.getRegionName()); - // Erase the current version of root meta for this test. - d.deleteColumn(HConstants.CATALOG_FAMILY, HConstants.META_VERSION_QUALIFIER); - HTable rootTable = - new HTable(TEST_UTIL.getConfiguration(), HConstants.ROOT_TABLE_NAME); - try { - rootTable.delete(d); - } finally { - rootTable.close(); - } - } - - public static void assertEquals(int expected, int actual) { - if (expected != actual) { - throw new AssertionFailedError("expected:<" + - expected + "> but was:<" + - actual + ">"); - } - } - - public static void assertEquals(boolean expected, boolean actual) { - if (expected != actual) { - throw new AssertionFailedError("expected:<" + - expected + "> but was:<" + - actual + ">"); - } - } - - - /** - * @param c - * @param htd - * @param family - * @param numRegions - * @return - * @throws IOException - * @deprecated Just for testing migration of meta from 0.90 to 0.92... will be - * removed thereafter - */ - public int createMultiRegionsWithLegacyHRI(final Configuration c, - final HTableDescriptor htd, final byte [] family, int numRegions) - throws IOException { - if (numRegions < 3) throw new IOException("Must create at least 3 regions"); - byte [] startKey = Bytes.toBytes("aaaaa"); - byte [] endKey = Bytes.toBytes("zzzzz"); - byte [][] splitKeys = Bytes.split(startKey, endKey, numRegions - 3); - byte [][] regionStartKeys = new byte[splitKeys.length+1][]; - for (int i=0;i newRegions - = new ArrayList(startKeys.length); - int count = 0; - for (int i = 0; i < startKeys.length; i++) { - int j = (i + 1) % startKeys.length; - HRegionInfo090x hri = new HRegionInfo090x(htd, - startKeys[i], startKeys[j]); - Put put = new Put(hri.getRegionName()); - put.setWriteToWAL(false); - put.add(HConstants.CATALOG_FAMILY, HConstants.REGIONINFO_QUALIFIER, - Writables.getBytes(hri)); - meta.put(put); - LOG.info("createMultiRegions: PUT inserted " + hri.toString()); - - newRegions.add(hri); - count++; - } - meta.close(); - return count; - } - - int createMultiRegionsWithNewHRI(final Configuration c, - final HTableDescriptor htd, final byte [] family, int numRegions) - throws IOException { - if (numRegions < 3) throw new IOException("Must create at least 3 regions"); - byte [] startKey = Bytes.toBytes("aaaaa"); - byte [] endKey = Bytes.toBytes("zzzzz"); - byte [][] splitKeys = Bytes.split(startKey, endKey, numRegions - 3); - byte [][] regionStartKeys = new byte[splitKeys.length+1][]; - for (int i=0;i newRegions - = new ArrayList(startKeys.length); - int count = 0; - for (int i = 0; i < startKeys.length; i++) { - int j = (i + 1) % startKeys.length; - HRegionInfo hri = new HRegionInfo(htd.getName(), - startKeys[i], startKeys[j]); - Put put = new Put(hri.getRegionName()); - put.setWriteToWAL(false); - put.add(HConstants.CATALOG_FAMILY, HConstants.REGIONINFO_QUALIFIER, - Writables.getBytes(hri)); - meta.put(put); - LOG.info("createMultiRegions: PUT inserted " + hri.toString()); - - newRegions.add(hri); - count++; - } - meta.close(); - return count; - } - - @org.junit.Rule - public org.apache.hadoop.hbase.ResourceCheckerJUnitRule cu = - new org.apache.hadoop.hbase.ResourceCheckerJUnitRule(); -} - diff --git src/test/java/org/apache/hadoop/hbase/coprocessor/SimpleRegionObserver.java src/test/java/org/apache/hadoop/hbase/coprocessor/SimpleRegionObserver.java index dacb936..a2f5dfc 100644 --- src/test/java/org/apache/hadoop/hbase/coprocessor/SimpleRegionObserver.java +++ src/test/java/org/apache/hadoop/hbase/coprocessor/SimpleRegionObserver.java @@ -73,8 +73,6 @@ public class SimpleRegionObserver extends BaseRegionObserver { boolean hadPostPut = false; boolean hadPreDeleted = false; boolean hadPostDeleted = false; - boolean hadPreGetClosestRowBefore = false; - boolean hadPostGetClosestRowBefore = false; boolean hadPreIncrement = false; boolean hadPostIncrement = false; boolean hadPreWALRestored = false; @@ -345,32 +343,6 @@ public class SimpleRegionObserver extends BaseRegionObserver { } @Override - public void preGetClosestRowBefore(final ObserverContext c, - final byte[] row, final byte[] family, final Result result) - throws IOException { - RegionCoprocessorEnvironment e = c.getEnvironment(); - assertNotNull(e); - assertNotNull(e.getRegion()); - assertNotNull(row); - assertNotNull(result); - if (beforeDelete) { - hadPreGetClosestRowBefore = true; - } - } - - @Override - public void postGetClosestRowBefore(final ObserverContext c, - final byte[] row, final byte[] family, final Result result) - throws IOException { - RegionCoprocessorEnvironment e = c.getEnvironment(); - assertNotNull(e); - assertNotNull(e.getRegion()); - assertNotNull(row); - assertNotNull(result); - hadPostGetClosestRowBefore = true; - } - - @Override public Result preIncrement(final ObserverContext c, final Increment increment) throws IOException { hadPreIncrement = true; diff --git src/test/java/org/apache/hadoop/hbase/master/MockRegionServer.java src/test/java/org/apache/hadoop/hbase/master/MockRegionServer.java index d2b3060..8925d58 100644 --- src/test/java/org/apache/hadoop/hbase/master/MockRegionServer.java +++ src/test/java/org/apache/hadoop/hbase/master/MockRegionServer.java @@ -237,13 +237,6 @@ class MockRegionServer implements HRegionInterface, RegionServerServices { } @Override - public Result getClosestRowBefore(byte[] regionName, byte[] row, - byte[] family) throws IOException { - // TODO Auto-generated method stub - return null; - } - - @Override public Result get(byte[] regionName, Get get) throws IOException { Map m = this.gets.get(regionName); if (m == null) return null; diff --git src/test/java/org/apache/hadoop/hbase/migration/TestMigration.java src/test/java/org/apache/hadoop/hbase/migration/TestMigration.java new file mode 100644 index 0000000..e637c31 --- /dev/null +++ src/test/java/org/apache/hadoop/hbase/migration/TestMigration.java @@ -0,0 +1,78 @@ +/** + * 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.migration; + + +import java.io.IOException; + +import junit.framework.Assert; + +import org.apache.hadoop.hbase.*; +import org.apache.hadoop.hbase.util.Bytes; +import org.apache.hadoop.hbase.catalog.MetaMigrationRemovingHTD; +import org.apache.hadoop.hbase.util.Writables; +import org.junit.Test; +import org.junit.experimental.categories.Category; + +@Category(LargeTests.class) +public class TestMigration { + @Test + public void testMigrateHRegionInfoFromVersion0toVersion2() + throws IOException { + HTableDescriptor htd = + getHTableDescriptor("testMigrateHRegionInfoFromVersion0toVersion2"); + HRegionInfo090x ninety = + new HRegionInfo090x(htd, HConstants.EMPTY_START_ROW, HConstants.EMPTY_END_ROW); + byte [] bytes = Writables.getBytes(ninety); + // Now deserialize into an HRegionInfo + HRegionInfo hri = Writables.getHRegionInfo(bytes); + Assert.assertEquals(hri.getTableNameAsString(), + ninety.getTableDesc().getNameAsString()); + Assert.assertEquals(HRegionInfo.VERSION, hri.getVersion()); + } + + @Test + public void testMigrateHRegionInfoFromVersion1toVersion2() + throws IOException { + String tableName = "testMigrateHRegionInfoFromVersion1toVersion2"; + byte[] tableNameB = Bytes.toBytes(tableName); + + HRegionInfo090x2 ninety = + new HRegionInfo090x2(tableNameB, + HConstants.EMPTY_START_ROW, + HConstants.EMPTY_END_ROW); + byte [] bytes = Writables.getBytes(ninety); + // Now deserialize into an HRegionInfo + HRegionInfo hri = Writables.getHRegionInfo(bytes); + Assert.assertEquals(hri.getTableNameAsString(), + Bytes.toString(ninety.getTableName())); + Assert.assertEquals(HRegionInfo.VERSION, hri.getVersion()); + } + + + private HTableDescriptor getHTableDescriptor(final String name) { + HTableDescriptor htd = new HTableDescriptor(name); + htd.addFamily(new HColumnDescriptor("family")); + return htd; + } + + @org.junit.Rule + public org.apache.hadoop.hbase.ResourceCheckerJUnitRule cu = + new org.apache.hadoop.hbase.ResourceCheckerJUnitRule(); +} + diff --git src/test/java/org/apache/hadoop/hbase/migration/TestMigrationFrom090To092.java src/test/java/org/apache/hadoop/hbase/migration/TestMigrationFrom090To092.java deleted file mode 100644 index c3651ac..0000000 --- src/test/java/org/apache/hadoop/hbase/migration/TestMigrationFrom090To092.java +++ /dev/null @@ -1,62 +0,0 @@ -/** - * 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.migration; - - -import java.io.IOException; - -import junit.framework.Assert; - -import org.apache.hadoop.hbase.*; -import org.apache.hadoop.hbase.catalog.MetaMigrationRemovingHTD; -import org.apache.hadoop.hbase.util.Writables; -import org.junit.Test; -import org.junit.experimental.categories.Category; - -/** - * Migration tests that do not need spin up of a cluster. - * @deprecated Remove after we release 0.92 - */ -@Category(SmallTests.class) -public class TestMigrationFrom090To092 { - @Test - public void testMigrateHRegionInfoFromVersion0toVersion1() - throws IOException { - HTableDescriptor htd = - getHTableDescriptor("testMigrateHRegionInfoFromVersion0toVersion1"); - HRegionInfo090x ninety = - new HRegionInfo090x(htd, HConstants.EMPTY_START_ROW, HConstants.EMPTY_END_ROW); - byte [] bytes = Writables.getBytes(ninety); - // Now deserialize into an HRegionInfo - HRegionInfo hri = Writables.getHRegionInfo(bytes); - Assert.assertEquals(hri.getTableNameAsString(), - ninety.getTableDesc().getNameAsString()); - Assert.assertEquals(HRegionInfo.VERSION, hri.getVersion()); - } - - private HTableDescriptor getHTableDescriptor(final String name) { - HTableDescriptor htd = new HTableDescriptor(name); - htd.addFamily(new HColumnDescriptor("family")); - return htd; - } - - @org.junit.Rule - public org.apache.hadoop.hbase.ResourceCheckerJUnitRule cu = - new org.apache.hadoop.hbase.ResourceCheckerJUnitRule(); -} - diff --git src/test/java/org/apache/hadoop/hbase/regionserver/TestGetClosestAtOrBefore.java src/test/java/org/apache/hadoop/hbase/regionserver/TestGetClosestAtOrBefore.java deleted file mode 100644 index 5f97167..0000000 --- src/test/java/org/apache/hadoop/hbase/regionserver/TestGetClosestAtOrBefore.java +++ /dev/null @@ -1,348 +0,0 @@ -/** - * Copyright 2009 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 java.io.IOException; -import java.util.ArrayList; -import java.util.List; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.apache.hadoop.fs.FileSystem; -import org.apache.hadoop.fs.Path; -import org.apache.hadoop.hbase.*; -import org.apache.hadoop.hbase.client.Delete; -import org.apache.hadoop.hbase.client.Put; -import org.apache.hadoop.hbase.client.Result; -import org.apache.hadoop.hbase.client.Scan; -import org.apache.hadoop.hbase.util.Bytes; -import org.apache.hadoop.hbase.util.Writables; -import org.apache.hadoop.hdfs.MiniDFSCluster; -import org.junit.experimental.categories.Category; - -/** - * {@link TestGet} is a medley of tests of get all done up as a single test. - * This class - */ -@Category(SmallTests.class) -public class TestGetClosestAtOrBefore extends HBaseTestCase { - private static final Log LOG = LogFactory.getLog(TestGetClosestAtOrBefore.class); - - private static final byte[] T00 = Bytes.toBytes("000"); - private static final byte[] T10 = Bytes.toBytes("010"); - private static final byte[] T11 = Bytes.toBytes("011"); - private static final byte[] T12 = Bytes.toBytes("012"); - private static final byte[] T20 = Bytes.toBytes("020"); - private static final byte[] T30 = Bytes.toBytes("030"); - private static final byte[] T31 = Bytes.toBytes("031"); - 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 - * @param rowToFind - * @param answer Pass -1 if we're not to find anything. - * @return Row found. - * @throws IOException - */ - private byte [] findRow(final HRegion mr, final char table, - final int rowToFind, final int answer) - throws IOException { - byte [] tableb = Bytes.toBytes("" + table); - // Find the row. - byte [] tofindBytes = Bytes.toBytes((short)rowToFind); - byte [] metaKey = HRegionInfo.createRegionName(tableb, tofindBytes, - HConstants.NINES, false); - LOG.info("find=" + new String(metaKey)); - Result r = mr.getClosestRowBefore(metaKey); - if (answer == -1) { - assertNull(r); - return null; - } - assertTrue(Bytes.compareTo(Bytes.toBytes((short)answer), - extractRowFromMetaRow(r.getRow())) == 0); - return r.getRow(); - } - - private byte [] extractRowFromMetaRow(final byte [] b) { - int firstDelimiter = KeyValue.getDelimiter(b, 0, b.length, - HRegionInfo.DELIMITER); - int lastDelimiter = KeyValue.getDelimiterInReverse(b, 0, b.length, - HRegionInfo.DELIMITER); - int length = lastDelimiter - firstDelimiter - 1; - byte [] row = new byte[length]; - System.arraycopy(b, firstDelimiter + 1, row, 0, length); - return row; - } - - /** - * Test file of multiple deletes and with deletes as final key. - * @see HBASE-751 - */ - public void testGetClosestRowBefore3() throws IOException{ - HRegion region = null; - byte [] c0 = COLUMNS[0]; - byte [] c1 = COLUMNS[1]; - try { - HTableDescriptor htd = createTableDescriptor(getName()); - region = createNewHRegion(htd, null, null); - - Put p = new Put(T00); - p.add(c0, c0, T00); - region.put(p); - - p = new Put(T10); - p.add(c0, c0, T10); - region.put(p); - - p = new Put(T20); - p.add(c0, c0, T20); - region.put(p); - - Result r = region.getClosestRowBefore(T20, c0); - assertTrue(Bytes.equals(T20, r.getRow())); - - Delete d = new Delete(T20); - d.deleteColumn(c0, c0); - region.delete(d, null, false); - - r = region.getClosestRowBefore(T20, c0); - assertTrue(Bytes.equals(T10, r.getRow())); - - p = new Put(T30); - p.add(c0, c0, T30); - region.put(p); - - r = region.getClosestRowBefore(T30, c0); - assertTrue(Bytes.equals(T30, r.getRow())); - - d = new Delete(T30); - d.deleteColumn(c0, c0); - region.delete(d, null, false); - - r = region.getClosestRowBefore(T30, c0); - assertTrue(Bytes.equals(T10, r.getRow())); - r = region.getClosestRowBefore(T31, c0); - assertTrue(Bytes.equals(T10, r.getRow())); - - region.flushcache(); - - // try finding "010" after flush - r = region.getClosestRowBefore(T30, c0); - assertTrue(Bytes.equals(T10, r.getRow())); - r = region.getClosestRowBefore(T31, c0); - assertTrue(Bytes.equals(T10, r.getRow())); - - // Put into a different column family. Should make it so I still get t10 - p = new Put(T20); - p.add(c1, c1, T20); - region.put(p); - - r = region.getClosestRowBefore(T30, c0); - assertTrue(Bytes.equals(T10, r.getRow())); - r = region.getClosestRowBefore(T31, c0); - assertTrue(Bytes.equals(T10, r.getRow())); - - region.flushcache(); - - r = region.getClosestRowBefore(T30, c0); - assertTrue(Bytes.equals(T10, r.getRow())); - r = region.getClosestRowBefore(T31, c0); - assertTrue(Bytes.equals(T10, r.getRow())); - - // Now try combo of memcache and mapfiles. Delete the t20 COLUMS[1] - // in memory; make sure we get back t10 again. - d = new Delete(T20); - d.deleteColumn(c1, c1); - region.delete(d, null, false); - r = region.getClosestRowBefore(T30, c0); - assertTrue(Bytes.equals(T10, r.getRow())); - - // Ask for a value off the end of the file. Should return t10. - r = region.getClosestRowBefore(T31, c0); - assertTrue(Bytes.equals(T10, r.getRow())); - region.flushcache(); - r = region.getClosestRowBefore(T31, c0); - assertTrue(Bytes.equals(T10, r.getRow())); - - // Ok. Let the candidate come out of hfile but have delete of - // the candidate be in memory. - p = new Put(T11); - p.add(c0, c0, T11); - region.put(p); - d = new Delete(T10); - d.deleteColumn(c1, c1); - r = region.getClosestRowBefore(T12, c0); - assertTrue(Bytes.equals(T11, r.getRow())); - } finally { - if (region != null) { - try { - region.close(); - } catch (Exception e) { - e.printStackTrace(); - } - region.getLog().closeAndDelete(); - } - } - } - - /** For HBASE-694 */ - public void testGetClosestRowBefore2() throws IOException{ - HRegion region = null; - byte [] c0 = COLUMNS[0]; - try { - HTableDescriptor htd = createTableDescriptor(getName()); - region = createNewHRegion(htd, null, null); - - Put p = new Put(T10); - p.add(c0, c0, T10); - region.put(p); - - p = new Put(T30); - p.add(c0, c0, T30); - region.put(p); - - p = new Put(T40); - p.add(c0, c0, T40); - region.put(p); - - // try finding "035" - Result r = region.getClosestRowBefore(T35, c0); - assertTrue(Bytes.equals(T30, r.getRow())); - - region.flushcache(); - - // try finding "035" - r = region.getClosestRowBefore(T35, c0); - assertTrue(Bytes.equals(T30, r.getRow())); - - p = new Put(T20); - p.add(c0, c0, T20); - region.put(p); - - // try finding "035" - r = region.getClosestRowBefore(T35, c0); - assertTrue(Bytes.equals(T30, r.getRow())); - - region.flushcache(); - - // try finding "035" - r = region.getClosestRowBefore(T35, c0); - assertTrue(Bytes.equals(T30, r.getRow())); - } finally { - if (region != null) { - try { - region.close(); - } catch (Exception e) { - e.printStackTrace(); - } - region.getLog().closeAndDelete(); - } - } - } - - @org.junit.Rule - public org.apache.hadoop.hbase.ResourceCheckerJUnitRule cu = - new org.apache.hadoop.hbase.ResourceCheckerJUnitRule(); -} - diff --git src/test/java/org/apache/hadoop/hbase/regionserver/TestHRegionInfo.java src/test/java/org/apache/hadoop/hbase/regionserver/TestHRegionInfo.java index 6dfba41..575962f 100644 --- src/test/java/org/apache/hadoop/hbase/regionserver/TestHRegionInfo.java +++ src/test/java/org/apache/hadoop/hbase/regionserver/TestHRegionInfo.java @@ -30,8 +30,6 @@ import java.io.IOException; import org.apache.hadoop.hbase.*; import org.apache.hadoop.hbase.util.Bytes; import org.apache.hadoop.hbase.util.FSTableDescriptors; -import org.apache.hadoop.hbase.util.FSUtils; -import org.apache.hadoop.hbase.util.MD5Hash; import org.junit.Test; import org.junit.experimental.categories.Category; @@ -43,22 +41,24 @@ 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); + // This should not change as it changes the location on HDFS. + String md5HashInHex = "e3365833b0bc503b5c0f4e8441da5897"; 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 + "," - + id + "." + md5HashInHex + ".", - nameStr); + assertEquals(tableName + "!," + endKey + "," + id + "." + md5HashInHex + + ".", nameStr); } @Test diff --git src/test/java/org/apache/hadoop/hbase/regionserver/TestMinVersions.java src/test/java/org/apache/hadoop/hbase/regionserver/TestMinVersions.java index 33c78ab..fa1f37d 100644 --- src/test/java/org/apache/hadoop/hbase/regionserver/TestMinVersions.java +++ src/test/java/org/apache/hadoop/hbase/regionserver/TestMinVersions.java @@ -47,48 +47,6 @@ public class TestMinVersions extends HBaseTestCase { private final byte[] c0 = COLUMNS[0]; /** - * Verify behavior of getClosestBefore(...) - */ - public void testGetClosestBefore() throws Exception { - HTableDescriptor htd = createTableDescriptor(getName(), 1, 1000, 1, false); - HRegion region = createNewHRegion(htd, null, null); - - // 2s in the past - long ts = EnvironmentEdgeManager.currentTimeMillis() - 2000; - - Put p = new Put(T1, ts); - p.add(c0, c0, T1); - region.put(p); - - p = new Put(T1, ts+1); - p.add(c0, c0, T4); - region.put(p); - - p = new Put(T3, ts); - p.add(c0, c0, T3); - region.put(p); - - // now make sure that getClosestBefore(...) get can - // rows that would be expired without minVersion. - // also make sure it gets the latest version - Result r = region.getClosestRowBefore(T1, c0); - checkResult(r, c0, T4); - - r = region.getClosestRowBefore(T2, c0); - checkResult(r, c0, T4); - - // now flush/compact - region.flushcache(); - region.compactStores(true); - - r = region.getClosestRowBefore(T1, c0); - checkResult(r, c0, T4); - - r = region.getClosestRowBefore(T2, c0); - checkResult(r, c0, T4); - } - - /** * Test mixed memstore and storefile scanning * with minimum versions. */ 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/TestStorageClusterStatusModel.java src/test/java/org/apache/hadoop/hbase/rest/model/TestStorageClusterStatusModel.java index c44f720..32e91d9 100644 --- src/test/java/org/apache/hadoop/hbase/rest/model/TestStorageClusterStatusModel.java +++ src/test/java/org/apache/hadoop/hbase/rest/model/TestStorageClusterStatusModel.java @@ -45,25 +45,19 @@ public class TestStorageClusterStatusModel extends TestCase { " name=\"test1\" maxHeapSizeMB=\"1024\" heapSizeMB=\"128\">" + "" + + " memstoreSizeMB=\"0\"/>" + "" + ""+ + " memstoreSizeMB=\"0\"/>"+ ""; - private static final String AS_PB = - "CjsKBXRlc3QxEOO6i+eeJBgAIIABKIAIMiMKCS1ST09ULSwsMBABGAEgACgAMAA4AUACSAFQAVgB" + - "YAFoAQpHCgV0ZXN0MhD+krHwniQYACCABCiACDIvChUuTUVUQS4sLDEyNDYwMDAwNDM3MjQQARgB" + - "IAAoADAAOAFAAkgBUAFYAWABaAEYAiAAKQAAAAAAAPA/"; - + private static final String AS_PB = +"Ci0KBXRlc3QxEOO6i+eeJBgAIIABKIAIMhUKCS1ST09ULSwsMBABGAEgACgAMAAKOQoFdGVzdDIQ"+ +"/pKx8J4kGAAggAQogAgyIQoVLk1FVEEuLCwxMjQ2MDAwMDQzNzI0EAEYASAAKAAwABgCIAApAAAA"+ +"AAAA8D8="; + private JAXBContext context; public TestStorageClusterStatusModel() throws JAXBException { @@ -77,10 +71,9 @@ public class TestStorageClusterStatusModel extends TestCase { model.setRequests(0); model.setAverageLoad(1.0); model.addLiveNode("test1", 1245219839331L, 128, 1024) - .addRegion(Bytes.toBytes("-ROOT-,,0"), 1, 1, 0, 0, 0, 1, 2, 1, 1, 1, 1, 1); + .addRegion(Bytes.toBytes("-ROOT-,,0"), 1, 1, 0, 0, 0); model.addLiveNode("test2", 1245239331198L, 512, 1024) - .addRegion(Bytes.toBytes(".META.,,1246000043724"),1, 1, 0, 0, 0, - 1, 2, 1, 1, 1, 1, 1); + .addRegion(Bytes.toBytes(".META.,,1246000043724"),1, 1, 0, 0, 0); return model; } @@ -126,13 +119,6 @@ public class TestStorageClusterStatusModel extends TestCase { assertEquals(region.getStorefileSizeMB(), 0); assertEquals(region.getMemstoreSizeMB(), 0); assertEquals(region.getStorefileIndexSizeMB(), 0); - assertEquals(region.getReadRequestsCount(), 1); - assertEquals(region.getWriteRequestsCount(), 2); - assertEquals(region.getRootIndexSizeKB(), 1); - assertEquals(region.getTotalStaticIndexSizeKB(), 1); - assertEquals(region.getTotalStaticBloomSizeKB(), 1); - assertEquals(region.getTotalCompactingKVs(), 1); - assertEquals(region.getCurrentCompactedKVs(), 1); assertFalse(regions.hasNext()); node = nodes.next(); assertEquals(node.getName(), "test2"); @@ -147,14 +133,6 @@ public class TestStorageClusterStatusModel extends TestCase { assertEquals(region.getStorefileSizeMB(), 0); assertEquals(region.getMemstoreSizeMB(), 0); assertEquals(region.getStorefileIndexSizeMB(), 0); - assertEquals(region.getReadRequestsCount(), 1); - assertEquals(region.getWriteRequestsCount(), 2); - assertEquals(region.getRootIndexSizeKB(), 1); - assertEquals(region.getTotalStaticIndexSizeKB(), 1); - assertEquals(region.getTotalStaticBloomSizeKB(), 1); - assertEquals(region.getTotalCompactingKVs(), 1); - assertEquals(region.getCurrentCompactedKVs(), 1); - assertFalse(regions.hasNext()); assertFalse(nodes.hasNext()); } 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)); } diff --git src/test/java/org/apache/hadoop/hbase/thrift/TestThriftServer.java src/test/java/org/apache/hadoop/hbase/thrift/TestThriftServer.java index 444d6d5..a087faa 100644 --- src/test/java/org/apache/hadoop/hbase/thrift/TestThriftServer.java +++ src/test/java/org/apache/hadoop/hbase/thrift/TestThriftServer.java @@ -19,10 +19,6 @@ */ package org.apache.hadoop.hbase.thrift; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - import java.io.IOException; import java.nio.ByteBuffer; import java.util.ArrayList; @@ -32,10 +28,7 @@ import java.util.Map; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.hadoop.conf.Configuration; -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.*; import org.apache.hadoop.hbase.filter.ParseFilter; import org.apache.hadoop.hbase.thrift.generated.BatchMutation; import org.apache.hadoop.hbase.thrift.generated.ColumnDescriptor; @@ -55,6 +48,8 @@ import org.junit.BeforeClass; import org.junit.Test; import org.junit.experimental.categories.Category; +import static org.junit.Assert.*; + /** * Unit testing for ThriftServerRunner.HBaseHandler, a part of the * org.apache.hadoop.hbase.thrift package. @@ -91,28 +86,7 @@ public class TestThriftServer { UTIL.shutdownMiniCluster(); } - /** - * Runs all of the tests under a single JUnit test method. We - * consolidate all testing to one method because HBaseClusterTestCase - * is prone to OutOfMemoryExceptions when there are three or more - * JUnit test methods. - * - * @throws Exception - */ - @Test - public void testAll() throws Exception { - // Run all tests - doTestTableCreateDrop(); - doTestThriftMetrics(); - doTestTableMutations(); - doTestTableTimestampsAndColumns(); - doTestTableScanners(); - doTestGetTableRegions(); - doTestFilterRegistration(); - doTestGetRegionInfo(); - } - - /** + /** * Tests for creating, enabling, disabling, and deleting tables. Also * tests that creating a table with an invalid column name yields an * IllegalArgument exception. @@ -159,7 +133,7 @@ public class TestThriftServer { private static void setupMetricsContext() throws IOException { ContextFactory factory = ContextFactory.getFactory(); factory.setAttribute(ThriftMetrics.CONTEXT_NAME + ".class", - NoEmitMetricsContext.class.getName()); + NoEmitMetricsContext.class.getName()); MetricsUtil.getContext(ThriftMetrics.CONTEXT_NAME) .createRecord(ThriftMetrics.CONTEXT_NAME).remove(); } @@ -208,6 +182,7 @@ public class TestThriftServer { * * @throws Exception */ + @Test public void doTestTableMutations() throws Exception { // Setup ThriftServerRunner.HBaseHandler handler = @@ -221,11 +196,11 @@ public class TestThriftServer { // Assert that the changes were made assertEquals(valueAname, - handler.get(tableAname, rowAname, columnAname, null).get(0).value); + handler.get(tableAname, rowAname, columnAname, null).get(0).value); TRowResult rowResult1 = handler.getRow(tableAname, rowAname, null).get(0); assertEquals(rowAname, rowResult1.row); assertEquals(valueBname, - rowResult1.columns.get(columnBname).value); + rowResult1.columns.get(columnBname).value); // Apply a few BatchMutations for rowA and rowB // rowAmutations.add(new Mutation(true, columnAname, null)); @@ -281,6 +256,7 @@ public class TestThriftServer { * * @throws Exception */ + @Test public void doTestTableTimestampsAndColumns() throws Exception { // Setup ThriftServerRunner.HBaseHandler handler = @@ -360,6 +336,7 @@ public class TestThriftServer { * * @throws Exception */ + @Test public void doTestTableScanners() throws Exception { // Setup ThriftServerRunner.HBaseHandler handler = @@ -429,6 +406,7 @@ public class TestThriftServer { * * @throws Exception */ + @Test public void doTestGetTableRegions() throws Exception { ThriftServerRunner.HBaseHandler handler = new ThriftServerRunner.HBaseHandler(UTIL.getConfiguration()); @@ -464,19 +442,15 @@ public class TestThriftServer { assertEquals("filterclass", registeredFilters.get("MyFilter")); } - public void doTestGetRegionInfo() throws Exception { - ThriftServerRunner.HBaseHandler handler = - new ThriftServerRunner.HBaseHandler(UTIL.getConfiguration()); - doTestGetRegionInfo(handler); - } - public static void doTestGetRegionInfo(Hbase.Iface handler) throws Exception { // Create tableA and add two columns to rowA handler.createTable(tableAname, getColumnDescriptors()); try { handler.mutateRow(tableAname, rowAname, getMutations(), null); - byte[] searchRow = HRegionInfo.createRegionName( - tableAname.array(), rowAname.array(), HConstants.NINES, false); + byte[] searchRow = HRegionInfo.createRegionName(tableAname.array(), + rowAname.array(), + Long.parseLong(HConstants.NINES), + false); TRegionInfo regionInfo = handler.getRegionInfo(ByteBuffer.wrap(searchRow)); assertTrue(Bytes.toStringBinary(regionInfo.getName()).startsWith( Bytes.toStringBinary(tableAname))); @@ -575,6 +549,58 @@ public class TestThriftServer { handler.scannerClose(scannerId); } + + /** + * Tests for creating, enabling, disabling, and deleting tables. Also + * tests that creating a table with an invalid column name yields an + * IllegalArgument exception. + * + * @throws Exception + */ + @Test + public void doTestGetRegionInfo() throws Exception { + ThriftServerRunner.HBaseHandler handler = + new ThriftServerRunner.HBaseHandler(UTIL.getConfiguration()); + + createTestTables(handler); + + ByteBuffer searchRow; + byte[] startRow; + byte[] tableName; + TRegionInfo regionInfo; + + startRow = HTableDescriptor.getStartRow(tableAname.array(), + "".getBytes()); + searchRow = ByteBuffer.wrap(startRow); + regionInfo = handler.getRegionInfo(searchRow); + tableName = HRegionInfo.parseRegionName(regionInfo.getName())[0]; + assertArrayEquals(tableAname.array(), tableName); + + startRow = HTableDescriptor.getStartRow(tableAname.array(), + "zzzzz".getBytes()); + searchRow = ByteBuffer.wrap(startRow); + regionInfo = handler.getRegionInfo(searchRow); + tableName = HRegionInfo.parseRegionName(regionInfo.getName())[0]; + assertArrayEquals(tableAname.array(), tableName); + + + startRow = HTableDescriptor.getStartRow(tableBname.array(), + "".getBytes()); + searchRow = ByteBuffer.wrap(startRow); + regionInfo = handler.getRegionInfo(searchRow); + tableName = HRegionInfo.parseRegionName(regionInfo.getName())[0]; + assertArrayEquals(tableBname.array(), tableName); + + startRow = HTableDescriptor.getStartRow(tableBname.array(), + "zzzzz".getBytes()); + searchRow = ByteBuffer.wrap(startRow); + regionInfo = handler.getRegionInfo(searchRow); + tableName = HRegionInfo.parseRegionName(regionInfo.getName())[0]; + assertArrayEquals(tableBname.array(), tableName); + + dropTestTables(handler); + } + @org.junit.Rule public org.apache.hadoop.hbase.ResourceCheckerJUnitRule cu = new org.apache.hadoop.hbase.ResourceCheckerJUnitRule();