HBASE-649 API polluted with default and protected access data members and methods

HBASE-650 Add String versions of get, scanner, put in HTable
HBASE-656 Do not retry exceptions such as unknown scanner or illegal argument
A  src/java/org/apache/hadoop/hbase/ColumnNameParseException.java
A  src/java/org/apache/hadoop/hbase/LeaseException.java
    Added.  Thrown instead of IllegalArgumentExceptions
M  src/java/org/apache/hadoop/hbase/Leases.java
    Use new LeaseException in place of IllegalArgument
M  src/java/org/apache/hadoop/hbase/HStoreKey.java
    Use new ColumnNameParse in place of IllegalArgument
M  src/java/org/apache/hadoop/hbase/master/ServerManager.java
    Log at debug if LeaseException (Not important if it happens).
A  src/java/org/apache/hadoop/hbase/DoNotRetryIOException.java
    An IOE that shouldn't be retried.
M  src/java/org/apache/hadoop/hbase/InvalidColumnNameException.java
M  src/java/org/apache/hadoop/hbase/UnknownScannerException.java
    Inherit from DoNotRetryIOException else we keep trying.
M  src/java/org/apache/hadoop/hbase/util/Bytes.java
    (toByteArrays): Added one to handle [] String.
M  src/java/org/apache/hadoop/hbase/client/HTable.java
    Make String overrides of all methods.  Made data members
    private (turns out a bunch arent' even used).  Stopped it
    inheriting from HConstants so we don't have big dump of
    all HConstants as first thing in javadoc.
M  src/java/org/apache/hadoop/hbase/client/HConnectionManager.java
    If instance of DoNotRetryIOException, let the exception out.
M  src/java/org/apache/hadoop/hbase/client/HBaseAdmin.java
    Make String overrides of all methods.  Stopped it
    inheriting from HConstants so we don't have big dump of
    all HConstants as first thing in javadoc.


git-svn-id: https://svn.apache.org/repos/asf/hadoop/hbase/trunk@661541 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Michael Stack 2008-05-30 00:51:43 +00:00
parent f8c4649209
commit f328681e00
13 changed files with 552 additions and 88 deletions

View File

@ -29,8 +29,11 @@ Hbase Change Log
HBASE-646 EOFException opening HStoreFile info file (spin on HBASE-645and 550)
HBASE-648 If mapfile index is empty, run repair
HBASE-640 TestMigrate failing on hudson
HASE-651 Table.commit should throw NoSuchColumnFamilyException if column
HBASE-651 Table.commit should throw NoSuchColumnFamilyException if column
family doesn't exist
HBASE-649 API polluted with default and protected access data members and methods
HBASE-650 Add String versions of get, scanner, put in HTable
HBASE-656 Do not retry exceptions such as unknown scanner or illegal argument
IMPROVEMENTS
HBASE-559 MR example job to count table rows

View File

@ -0,0 +1,33 @@
/**
* Copyright 2008 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;
/**
* Thrown if issue with passed column name.
*/
public class ColumnNameParseException extends DoNotRetryIOException {
public ColumnNameParseException() {
super();
}
public ColumnNameParseException(String message) {
super(message);
}
}

View File

@ -0,0 +1,36 @@
/**
* Copyright 2008 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;
import java.io.IOException;
/**
* Subclass if exception is not meant to be retried: e.g.
* {@link UnknownScannerException}
*/
public class DoNotRetryIOException extends IOException {
public DoNotRetryIOException() {
super();
}
public DoNotRetryIOException(String message) {
super(message);
}
}

View File

@ -300,12 +300,14 @@ public class HStoreKey implements WritableComparable {
/**
* @param column
* @return New byte array that holds <code>column</code> family prefix.
* @throws ColumnNameParseException
* @see #parseColumn(byte[])
*/
public static byte [] getFamily(final byte [] column) {
public static byte [] getFamily(final byte [] column)
throws ColumnNameParseException {
int index = getFamilyDelimiterIndex(column);
if (index <= 0) {
throw new IllegalArgumentException("No ':' delimiter between " +
throw new ColumnNameParseException("No ':' delimiter between " +
"column family and qualifier in the passed column name <" +
Bytes.toString(column) + ">");
}
@ -370,12 +372,14 @@ public class HStoreKey implements WritableComparable {
* @return Return array of size two whose first element has the family
* prefix of passed column <code>c</code> and whose second element is the
* column qualifier.
* @throws ColumnNameParseException
*/
public static byte [][] parseColumn(final byte [] c) {
public static byte [][] parseColumn(final byte [] c)
throws ColumnNameParseException {
byte [][] result = new byte [2][];
int index = getFamilyDelimiterIndex(c);
if (index == -1) {
throw new IllegalArgumentException("Impossible column name: " + c);
throw new ColumnNameParseException("Impossible column name: " + c);
}
result[0] = new byte [index];
System.arraycopy(c, 0, result[0], 0, index);

View File

@ -19,12 +19,11 @@
*/
package org.apache.hadoop.hbase;
import java.io.IOException;
/**
* Thrown when an invalid column name is encountered
*/
public class InvalidColumnNameException extends IOException {
public class InvalidColumnNameException extends DoNotRetryIOException {
private static final long serialVersionUID = 1L << 29 - 1L;
/** default constructor */
public InvalidColumnNameException() {
@ -38,4 +37,4 @@ public class InvalidColumnNameException extends IOException {
public InvalidColumnNameException(String s) {
super(s);
}
}
}

View File

@ -0,0 +1,30 @@
/**
* Copyright 2008 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;
public class LeaseException extends DoNotRetryIOException {
public LeaseException() {
super();
}
public LeaseException(String message) {
super(message);
}
}

View File

@ -165,12 +165,13 @@ public class Leases extends Thread {
* Renew a lease
*
* @param leaseName name of lease
* @throws LeaseException
*/
public void renewLease(final String leaseName) {
public void renewLease(final String leaseName) throws LeaseException {
synchronized (leaseQueue) {
Lease lease = leases.get(leaseName);
if (lease == null) {
throw new IllegalArgumentException("lease '" + leaseName +
throw new LeaseException("lease '" + leaseName +
"' does not exist");
}
leaseQueue.remove(lease);
@ -183,13 +184,13 @@ public class Leases extends Thread {
* Client explicitly cancels a lease.
*
* @param leaseName name of lease
* @throws LeaseException
*/
public void cancelLease(final String leaseName) {
public void cancelLease(final String leaseName) throws LeaseException {
synchronized (leaseQueue) {
Lease lease = leases.remove(leaseName);
if (lease == null) {
throw new IllegalArgumentException("lease '" + leaseName +
"' does not exist");
throw new LeaseException("lease '" + leaseName + "' does not exist");
}
leaseQueue.remove(lease);
}

View File

@ -19,12 +19,11 @@
*/
package org.apache.hadoop.hbase;
import java.io.IOException;
/**
* Thrown if a region server is passed an unknown scanner id
*/
public class UnknownScannerException extends IOException {
public class UnknownScannerException extends DoNotRetryIOException {
private static final long serialVersionUID = 993179627856392526L;
/** constructor */

View File

@ -47,9 +47,8 @@ import org.apache.hadoop.ipc.RemoteException;
/**
* Provides administrative functions for HBase
*/
public class HBaseAdmin implements HConstants {
protected final Log LOG = LogFactory.getLog(this.getClass().getName());
public class HBaseAdmin {
private final Log LOG = LogFactory.getLog(this.getClass().getName());
private final HConnection connection;
private final long pause;
private final int numRetries;
@ -86,9 +85,9 @@ public class HBaseAdmin implements HConstants {
* @return True if table exists already.
* @throws MasterNotRunningException
*/
public boolean tableExists(final String tableName)
public boolean tableExists(final Text tableName)
throws MasterNotRunningException {
return tableExists(Bytes.toBytes(tableName));
return tableExists(tableName.getBytes());
}
/**
@ -96,11 +95,11 @@ public class HBaseAdmin implements HConstants {
* @return True if table exists already.
* @throws MasterNotRunningException
*/
public boolean tableExists(final Text tableName)
public boolean tableExists(final String tableName)
throws MasterNotRunningException {
return tableExists(tableName.getBytes());
return tableExists(Bytes.toBytes(tableName));
}
/**
* @param tableName Table to check.
* @return True if table exists already.
@ -147,7 +146,7 @@ public class HBaseAdmin implements HConstants {
for (int tries = 0; tries < numRetries; tries++) {
try {
// Wait for new table to come on-line
connection.locateRegion(desc.getName(), EMPTY_START_ROW);
connection.locateRegion(desc.getName(), HConstants.EMPTY_START_ROW);
break;
} catch (TableNotFoundException e) {
@ -199,6 +198,16 @@ public class HBaseAdmin implements HConstants {
deleteTable(tableName.getBytes());
}
/**
* Deletes a table
*
* @param tableName name of table to delete
* @throws IOException
*/
public void deleteTable(final String tableName) throws IOException {
deleteTable(Bytes.toBytes(tableName));
}
/**
* Deletes a table
*
@ -226,14 +235,15 @@ public class HBaseAdmin implements HConstants {
try {
scannerId =
server.openScanner(firstMetaServer.getRegionInfo().getRegionName(),
COL_REGIONINFO_ARRAY, tableName, HConstants.LATEST_TIMESTAMP, null);
HConstants.COL_REGIONINFO_ARRAY, tableName,
HConstants.LATEST_TIMESTAMP, null);
RowResult values = server.next(scannerId);
if (values == null || values.size() == 0) {
break;
}
boolean found = false;
for (Map.Entry<byte [], Cell> e: values.entrySet()) {
if (Bytes.equals(e.getKey(), COL_REGIONINFO)) {
if (Bytes.equals(e.getKey(), HConstants.COL_REGIONINFO)) {
info = (HRegionInfo) Writables.getWritable(
e.getValue().getValue(), info);
@ -282,7 +292,17 @@ public class HBaseAdmin implements HConstants {
public void enableTable(final Text tableName) throws IOException {
enableTable(tableName.getBytes());
}
/**
* Brings a table on-line (enables it)
*
* @param tableName name of the table
* @throws IOException
*/
public void enableTable(final String tableName) throws IOException {
enableTable(Bytes.toBytes(tableName));
}
/**
* Brings a table on-line (enables it)
*
@ -315,7 +335,8 @@ public class HBaseAdmin implements HConstants {
try {
scannerId =
server.openScanner(firstMetaServer.getRegionInfo().getRegionName(),
COL_REGIONINFO_ARRAY, tableName, HConstants.LATEST_TIMESTAMP, null);
HConstants.COL_REGIONINFO_ARRAY, tableName,
HConstants.LATEST_TIMESTAMP, null);
boolean isenabled = false;
while (true) {
@ -329,7 +350,7 @@ public class HBaseAdmin implements HConstants {
}
valuesfound += 1;
for (Map.Entry<byte [], Cell> e: values.entrySet()) {
if (Bytes.equals(e.getKey(), COL_REGIONINFO)) {
if (Bytes.equals(e.getKey(), HConstants.COL_REGIONINFO)) {
info = (HRegionInfo) Writables.getWritable(
e.getValue().getValue(), info);
@ -391,7 +412,18 @@ public class HBaseAdmin implements HConstants {
public void disableTable(final Text tableName) throws IOException {
disableTable(tableName.getBytes());
}
/**
* Disables a table (takes it off-line) If it is being served, the master
* will tell the servers to stop serving it.
*
* @param tableName name of table
* @throws IOException
*/
public void disableTable(final String tableName) throws IOException {
disableTable(Bytes.toBytes(tableName));
}
/**
* Disables a table (takes it off-line) If it is being served, the master
* will tell the servers to stop serving it.
@ -423,7 +455,8 @@ public class HBaseAdmin implements HConstants {
try {
scannerId =
server.openScanner(firstMetaServer.getRegionInfo().getRegionName(),
COL_REGIONINFO_ARRAY, tableName, HConstants.LATEST_TIMESTAMP, null);
HConstants.COL_REGIONINFO_ARRAY, tableName,
HConstants.LATEST_TIMESTAMP, null);
boolean disabled = false;
while (true) {
RowResult values = server.next(scannerId);
@ -435,7 +468,7 @@ public class HBaseAdmin implements HConstants {
}
valuesfound += 1;
for (Map.Entry<byte [], Cell> e: values.entrySet()) {
if (Bytes.equals(e.getKey(), COL_REGIONINFO)) {
if (Bytes.equals(e.getKey(), HConstants.COL_REGIONINFO)) {
info = (HRegionInfo) Writables.getWritable(
e.getValue().getValue(), info);
@ -497,7 +530,19 @@ public class HBaseAdmin implements HConstants {
throws IOException {
addColumn(tableName.getBytes(), column);
}
/**
* Add a column to an existing table
*
* @param tableName name of the table to add column to
* @param column column descriptor of column to be added
* @throws IOException
*/
public void addColumn(final String tableName, HColumnDescriptor column)
throws IOException {
addColumn(Bytes.toBytes(tableName), column);
}
/**
* Add a column to an existing table
*
@ -529,7 +574,19 @@ public class HBaseAdmin implements HConstants {
throws IOException {
deleteColumn(tableName.getBytes(), columnName.getBytes());
}
/**
* Delete a column from a table
*
* @param tableName name of table
* @param columnName name of column to be deleted
* @throws IOException
*/
public void deleteColumn(final String tableName, final String columnName)
throws IOException {
deleteColumn(Bytes.toBytes(tableName), Bytes.toBytes(columnName));
}
/**
* Delete a column from a table
*
@ -563,7 +620,22 @@ public class HBaseAdmin implements HConstants {
throws IOException {
modifyColumn(tableName.getBytes(), columnName.getBytes(), descriptor);
}
/**
* Modify an existing column family on a table
*
* @param tableName name of table
* @param columnName name of column to be modified
* @param descriptor new column descriptor to use
* @throws IOException
*/
public void modifyColumn(final String tableName, final String columnName,
HColumnDescriptor descriptor)
throws IOException {
modifyColumn(Bytes.toBytes(tableName), Bytes.toBytes(columnName),
descriptor);
}
/**
* Modify an existing column family on a table
*
@ -606,8 +678,8 @@ public class HBaseAdmin implements HConstants {
private HRegionLocation getFirstMetaServerForTable(final byte [] tableName)
throws IOException {
return connection.locateRegion(META_TABLE_NAME,
HRegionInfo.createRegionName(tableName, null, NINES));
return connection.locateRegion(HConstants.META_TABLE_NAME,
HRegionInfo.createRegionName(tableName, null, HConstants.NINES));
}
/**
@ -622,4 +694,4 @@ public class HBaseAdmin implements HConstants {
copyOfConf.setInt("hbase.client.retries.number", 1);
new HBaseAdmin(copyOfConf);
}
}
}

View File

@ -31,6 +31,7 @@ import java.util.concurrent.ConcurrentHashMap;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.hbase.DoNotRetryIOException;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.HConstants;
import org.apache.hadoop.hbase.HRegionInfo;
@ -732,6 +733,9 @@ public class HConnectionManager implements HConstants {
if (t instanceof RemoteException) {
t = RemoteExceptionHandler.decodeRemoteException((RemoteException) t);
}
if (t instanceof DoNotRetryIOException) {
throw (DoNotRetryIOException)t;
}
exceptions.add(t);
if (tries == numRetries - 1) {
throw new RetriesExhaustedException(callable.getServerName(),

View File

@ -25,7 +25,6 @@ import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Random;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@ -48,20 +47,45 @@ import org.apache.hadoop.io.Text;
/**
* Used to communicate with a single HBase table
*/
public class HTable implements HConstants {
protected final Log LOG = LogFactory.getLog(this.getClass());
public class HTable {
private final Log LOG = LogFactory.getLog(this.getClass());
private final HConnection connection;
private final byte [] tableName;
private HBaseConfiguration configuration;
protected final HConnection connection;
protected final byte [] tableName;
protected final long pause;
protected final int numRetries;
protected Random rand;
protected HBaseConfiguration configuration;
/**
* Creates an object to access a HBase table
*
* @param tableName name of the table
* @throws IOException
*/
public HTable(final Text tableName)
throws IOException {
this(new HBaseConfiguration(), tableName.getBytes());
}
/**
* Creates an object to access a HBase table
*
* @param tableName name of the table
* @throws IOException
*/
public HTable(final String tableName)
throws IOException {
this(new HBaseConfiguration(), Bytes.toBytes(tableName));
}
/**
* Creates an object to access a HBase table
*
* @param tableName name of the table
* @throws IOException
*/
public HTable(final byte [] tableName)
throws IOException {
this(new HBaseConfiguration(), tableName);
}
protected volatile boolean tableDoesNotExist;
// For row mutation operations
/**
* Creates an object to access a HBase table
*
@ -73,7 +97,7 @@ public class HTable implements HConstants {
throws IOException {
this(conf, tableName.getBytes());
}
/**
* Creates an object to access a HBase table
*
@ -98,10 +122,29 @@ public class HTable implements HConstants {
this.connection = HConnectionManager.getConnection(conf);
this.configuration = conf;
this.tableName = tableName;
this.pause = conf.getLong("hbase.client.pause", 10 * 1000);
this.numRetries = conf.getInt("hbase.client.retries.number", 5);
this.rand = new Random();
this.connection.locateRegion(tableName, EMPTY_START_ROW);
this.connection.locateRegion(tableName, HConstants.EMPTY_START_ROW);
}
/**
* Find region location hosting passed row using cached info
* @param row Row to find.
* @return Location of row.
* @throws IOException
*/
public HRegionLocation getRegionLocation(final Text row)
throws IOException {
return connection.getRegionLocation(tableName, row.getBytes(), false);
}
/**
* Find region location hosting passed row using cached info
* @param row Row to find.
* @return Location of row.
* @throws IOException
*/
public HRegionLocation getRegionLocation(final String row)
throws IOException {
return connection.getRegionLocation(tableName, Bytes.toBytes(row), false);
}
/**
@ -115,17 +158,17 @@ public class HTable implements HConstants {
return connection.getRegionLocation(tableName, row, false);
}
/** @return the connection */
public HConnection getConnection() {
return connection;
}
/** @return the table name */
public byte [] getTableName() {
return this.tableName;
}
protected HConnection getConnection() {
return this.connection;
}
/**
* TODO: Make the return read-only.
* @return table metadata
* @throws IOException
*/
@ -152,10 +195,12 @@ public class HTable implements HConstants {
final List<byte[]> keyList = new ArrayList<byte[]>();
MetaScannerVisitor visitor = new MetaScannerVisitor() {
public boolean processRow(RowResult rowResult,
HRegionLocation metaLocation, HRegionInfo info)
@SuppressWarnings("unused")
public boolean processRow(@SuppressWarnings("unused") RowResult rowResult,
@SuppressWarnings("unused") HRegionLocation metaLocation,
HRegionInfo info)
throws IOException {
if (!(Bytes.equals(info.getTableDesc().getName(), tableName))) {
if (!(Bytes.equals(info.getTableDesc().getName(), getTableName()))) {
return false;
}
if (!(info.isOffline() || info.isSplit())) {
@ -181,10 +226,11 @@ public class HTable implements HConstants {
new HashMap<HRegionInfo, HServerAddress>();
MetaScannerVisitor visitor = new MetaScannerVisitor() {
public boolean processRow(RowResult rowResult,
@SuppressWarnings("unused")
public boolean processRow(@SuppressWarnings("unused") RowResult rowResult,
HRegionLocation metaLocation, HRegionInfo info)
throws IOException {
if (!(Bytes.equals(info.getTableDesc().getName(), tableName))) {
if (!(Bytes.equals(info.getTableDesc().getName(), getTableName()))) {
return false;
}
if (!(info.isOffline() || info.isSplit())) {
@ -224,7 +270,34 @@ public class HTable implements HConstants {
throws IOException {
return get(row.getBytes(), column.getBytes(), numVersions);
}
/**
* Get a single value for the specified row and column
*
* @param row row key
* @param column column name
* @return value for specified row/column
* @throws IOException
*/
public Cell get(final String row, final String column)
throws IOException {
return get(Bytes.toBytes(row), Bytes.toBytes(column));
}
/**
* Get a single value for the specified row and column
*
* @param row row key
* @param column column name
* @param numVersions - number of versions to retrieve
* @return value for specified row/column
* @throws IOException
*/
public Cell[] get(final String row, final String column, int numVersions)
throws IOException {
return get(Bytes.toBytes(row), Bytes.toBytes(column), numVersions);
}
/**
* Get a single value for the specified row and column
*
@ -293,7 +366,24 @@ public class HTable implements HConstants {
throws IOException {
return get(row.getBytes(), column.getBytes(), timestamp, numVersions);
}
/**
* Get the specified number of versions of the specified row and column with
* the specified timestamp.
*
* @param row - row key
* @param column - column name
* @param timestamp - timestamp
* @param numVersions - number of versions to retrieve
* @return - array of values that match the above criteria
* @throws IOException
*/
public Cell[] get(final String row, final String column,
final long timestamp, final int numVersions)
throws IOException {
return get(Bytes.toBytes(row), Bytes.toBytes(column), timestamp, numVersions);
}
/**
* Get the specified number of versions of the specified row and column with
* the specified timestamp.
@ -339,6 +429,17 @@ public class HTable implements HConstants {
return getRow(row.getBytes());
}
/**
* Get all the data for the specified row at the latest timestamp
*
* @param row row key
* @return RowResult is empty if row does not exist.
* @throws IOException
*/
public RowResult getRow(final String row) throws IOException {
return getRow(Bytes.toBytes(row));
}
/**
* Get all the data for the specified row at the latest timestamp
*
@ -363,6 +464,19 @@ public class HTable implements HConstants {
return getRow(row.getBytes(), ts);
}
/**
* Get all the data for the specified row at a specified timestamp
*
* @param row row key
* @param ts timestamp
* @return RowResult is empty if row does not exist.
* @throws IOException
*/
public RowResult getRow(final String row, final long ts)
throws IOException {
return getRow(Bytes.toBytes(row), ts);
}
/**
* Get all the data for the specified row at a specified timestamp
*
@ -382,6 +496,7 @@ public class HTable implements HConstants {
}
);
}
/**
* Get selected columns for the specified row at the latest timestamp
*
@ -394,7 +509,20 @@ public class HTable implements HConstants {
throws IOException {
return getRow(row.getBytes(), Bytes.toByteArrays(columns));
}
/**
* Get selected columns for the specified row at the latest timestamp
*
* @param row row key
* @param columns Array of column names you want to retrieve.
* @return RowResult is empty if row does not exist.
* @throws IOException
*/
public RowResult getRow(final String row, final String [] columns)
throws IOException {
return getRow(Bytes.toBytes(row), Bytes.toByteArrays(columns));
}
/**
* Get selected columns for the specified row at the latest timestamp
*
@ -417,12 +545,27 @@ public class HTable implements HConstants {
* @return RowResult is empty if row does not exist.
* @throws IOException
*/
public RowResult getRow(final Text row, final Text[] columns,
public RowResult getRow(final Text row, final Text [] columns,
final long ts)
throws IOException {
return getRow(row.getBytes(), Bytes.toByteArrays(columns), ts);
}
/**
* Get selected columns for the specified row at a specified timestamp
*
* @param row row key
* @param columns Array of column names you want to retrieve.
* @param ts timestamp
* @return RowResult is empty if row does not exist.
* @throws IOException
*/
public RowResult getRow(final String row, final String [] columns,
final long ts)
throws IOException {
return getRow(Bytes.toBytes(row), Bytes.toByteArrays(columns), ts);
}
/**
* Get selected columns for the specified row at a specified timestamp
*
@ -462,6 +605,23 @@ public class HTable implements HConstants {
return getScanner(Bytes.toByteArrays(columns), HConstants.EMPTY_START_ROW);
}
/**
* Get a scanner on the current table starting at first row.
* Return the specified columns.
*
* @param columns columns to scan. If column name is a column family, all
* columns of the specified column family are returned. Its also possible
* to pass a regex in the column qualifier. A column qualifier is judged to
* be a regex if it contains at least one of the following characters:
* <code>\+|^&*$[]]}{)(</code>.
* @return scanner
* @throws IOException
*/
public Scanner getScanner(final String [] columns)
throws IOException {
return getScanner(Bytes.toByteArrays(columns), HConstants.EMPTY_START_ROW);
}
/**
* Get a scanner on the current table starting at the specified row.
* Return the specified columns.
@ -480,6 +640,24 @@ public class HTable implements HConstants {
return getScanner(Bytes.toByteArrays(columns), startRow.getBytes());
}
/**
* Get a scanner on the current table starting at the specified row.
* Return the specified columns.
*
* @param columns columns to scan. If column name is a column family, all
* columns of the specified column family are returned. Its also possible
* to pass a regex in the column qualifier. A column qualifier is judged to
* be a regex if it contains at least one of the following characters:
* <code>\+|^&*$[]]}{)(</code>.
* @param startRow starting row in table to scan
* @return scanner
* @throws IOException
*/
public Scanner getScanner(final String [] columns, final String startRow)
throws IOException {
return getScanner(Bytes.toByteArrays(columns), Bytes.toBytes(startRow));
}
/**
* Get a scanner on the current table starting at first row.
* Return the specified columns.
@ -604,7 +782,32 @@ public class HTable implements HConstants {
return getScanner(Bytes.toByteArrays(columns), startRow.getBytes(),
stopRow.getBytes(), timestamp);
}
/**
* Get a scanner on the current table starting at the specified row and
* ending just before <code>stopRow<code>.
* Return the specified columns.
*
* @param columns columns to scan. If column name is a column family, all
* columns of the specified column family are returned. Its also possible
* to pass a regex in the column qualifier. A column qualifier is judged to
* be a regex if it contains at least one of the following characters:
* <code>\+|^&*$[]]}{)(</code>.
* @param startRow starting row in table to scan
* @param stopRow Row to stop scanning on. Once we hit this row we stop
* returning values; i.e. we return the row before this one but not the
* <code>stopRow</code> itself.
* @param timestamp only return results whose timestamp <= this value
* @return scanner
* @throws IOException
*/
public Scanner getScanner(final String [] columns,
final String startRow, final String stopRow, final long timestamp)
throws IOException {
return getScanner(Bytes.toByteArrays(columns), Bytes.toBytes(startRow),
Bytes.toBytes(stopRow), timestamp);
}
/**
* Get a scanner on the current table starting at the specified row and
* ending just before <code>stopRow<code>.
@ -651,7 +854,29 @@ public class HTable implements HConstants {
return getScanner(Bytes.toByteArrays(columns), startRow.getBytes(),
timestamp, filter);
}
/**
* Get a scanner on the current table starting at the specified row.
* Return the specified columns.
*
* @param columns columns to scan. If column name is a column family, all
* columns of the specified column family are returned. Its also possible
* to pass a regex in the column qualifier. A column qualifier is judged to
* be a regex if it contains at least one of the following characters:
* <code>\+|^&*$[]]}{)(</code>.
* @param startRow starting row in table to scan
* @param timestamp only return results whose timestamp <= this value
* @param filter a row filter using row-key regexp and/or column data filter.
* @return scanner
* @throws IOException
*/
public Scanner getScanner(String[] columns,
String startRow, long timestamp, RowFilterInterface filter)
throws IOException {
return getScanner(Bytes.toByteArrays(columns), Bytes.toBytes(startRow),
timestamp, filter);
}
/**
* Get a scanner on the current table starting at the specified row.
* Return the specified columns.
@ -713,7 +938,18 @@ public class HTable implements HConstants {
* @throws IOException
*/
public void deleteAll(final Text row, final Text column) throws IOException {
deleteAll(row, column, LATEST_TIMESTAMP);
deleteAll(row, column, HConstants.LATEST_TIMESTAMP);
}
/**
* Delete all cells that match the passed row and column.
* @param row Row to update
* @param column name of column whose value is to be deleted
* @throws IOException
*/
public void deleteAll(final String row, final String column)
throws IOException {
deleteAll(row, column, HConstants.LATEST_TIMESTAMP);
}
/**
@ -729,6 +965,19 @@ public class HTable implements HConstants {
deleteAll(row.getBytes(), column.getBytes(), ts);
}
/**
* Delete all cells that match the passed row and column and whose
* timestamp is equal-to or older than the passed timestamp.
* @param row Row to update
* @param column name of column whose value is to be deleted
* @param ts Delete all cells of the same timestamp or older.
* @throws IOException
*/
public void deleteAll(final String row, final String column, final long ts)
throws IOException {
deleteAll(Bytes.toBytes(row), Bytes.toBytes(column), ts);
}
/**
* Delete all cells that match the passed row and column and whose
* timestamp is equal-to or older than the passed timestamp.
@ -761,6 +1010,19 @@ public class HTable implements HConstants {
deleteFamily(row.getBytes(), family.getBytes(),
HConstants.LATEST_TIMESTAMP);
}
/**
* Delete all cells for a row with matching column family at all timestamps.
*
* @param row The row to operate on
* @param family The column family to match
* @throws IOException
*/
public void deleteFamily(final String row, final String family)
throws IOException{
deleteFamily(Bytes.toBytes(row), Bytes.toBytes(family),
HConstants.LATEST_TIMESTAMP);
}
/**
* Delete all cells for a row with matching column family with timestamps
@ -809,6 +1071,7 @@ public class HTable implements HConstants {
* through them all.
*/
private class ClientScanner implements Scanner {
private final Log CLIENT_LOG = LogFactory.getLog(this.getClass());
private byte[][] columns;
private byte [] startRow;
protected long scanTime;
@ -828,8 +1091,8 @@ public class HTable implements HConstants {
protected ClientScanner(final byte[][] columns, final byte [] startRow,
final long timestamp, final RowFilterInterface filter)
throws IOException {
if (LOG.isDebugEnabled()) {
LOG.debug("Creating scanner over " + Bytes.toString(tableName) +
if (CLIENT_LOG.isDebugEnabled()) {
CLIENT_LOG.debug("Creating scanner over " + Bytes.toString(getTableName()) +
" starting at key '" + Bytes.toString(startRow) + "'");
}
// save off the simple parameters
@ -854,19 +1117,19 @@ public class HTable implements HConstants {
// close the previous scanner if it's open
if (this.callable != null) {
this.callable.setClose();
connection.getRegionServerWithRetries(callable);
getConnection().getRegionServerWithRetries(callable);
this.callable = null;
}
// if we're at the end of the table, then close and return false
// to stop iterating
if (currentRegion != null){
if (LOG.isDebugEnabled()) {
LOG.debug("Advancing forward from region " + currentRegion);
if (CLIENT_LOG.isDebugEnabled()) {
CLIENT_LOG.debug("Advancing forward from region " + currentRegion);
}
byte [] endKey = currentRegion.getEndKey();
if (endKey == null || Bytes.equals(endKey, EMPTY_BYTE_ARRAY)) {
if (endKey == null || Bytes.equals(endKey, HConstants.EMPTY_BYTE_ARRAY)) {
close();
return false;
}
@ -875,17 +1138,17 @@ public class HTable implements HConstants {
HRegionInfo oldRegion = this.currentRegion;
byte [] localStartKey = oldRegion == null? startRow: oldRegion.getEndKey();
if (LOG.isDebugEnabled()) {
LOG.debug("Advancing internal scanner to startKey at " +
if (CLIENT_LOG.isDebugEnabled()) {
CLIENT_LOG.debug("Advancing internal scanner to startKey at " +
Bytes.toString(localStartKey));
}
try {
callable = new ScannerCallable(connection, tableName, columns,
callable = new ScannerCallable(getConnection(), getTableName(), columns,
localStartKey, scanTime, filter);
// open a scanner on the region server starting at the
// beginning of the region
connection.getRegionServerWithRetries(callable);
getConnection().getRegionServerWithRetries(callable);
currentRegion = callable.getHRegionInfo();
} catch (IOException e) {
close();
@ -902,7 +1165,7 @@ public class HTable implements HConstants {
RowResult values = null;
do {
values = connection.getRegionServerWithRetries(callable);
values = getConnection().getRegionServerWithRetries(callable);
} while (values != null && values.size() == 0 && nextScanner());
if (values != null && values.size() != 0) {
@ -919,7 +1182,7 @@ public class HTable implements HConstants {
if (callable != null) {
callable.setClose();
try {
connection.getRegionServerWithRetries(callable);
getConnection().getRegionServerWithRetries(callable);
} catch (IOException e) {
// We used to catch this error, interpret, and rethrow. However, we
// have since decided that it's not nice for a scanner's close to

View File

@ -39,6 +39,7 @@ import org.apache.hadoop.hbase.HServerLoad;
import org.apache.hadoop.hbase.HServerAddress;
import org.apache.hadoop.hbase.HMsg;
import org.apache.hadoop.hbase.HRegionInfo;
import org.apache.hadoop.hbase.LeaseException;
import org.apache.hadoop.hbase.Leases;
import org.apache.hadoop.hbase.LeaseListener;
import org.apache.hadoop.hbase.HConstants;
@ -520,7 +521,14 @@ class ServerManager implements HConstants {
master.regionManager.unassignRootRegion();
}
LOG.info("Cancelling lease for " + serverName);
serverLeases.cancelLease(serverName);
try {
serverLeases.cancelLease(serverName);
} catch (LeaseException e) {
if (LOG.isDebugEnabled()) {
LOG.debug("Cancelling " + serverName + " got " + e.getMessage() +
"...continuing");
}
}
leaseCancelled = true;
// update load information

View File

@ -251,7 +251,19 @@ public class Bytes {
}
return result;
}
/**
* @param t
* @return Array of byte arrays made from passed array of Text
*/
public static byte [][] toByteArrays(final String [] t) {
byte [][] result = new byte[t.length][];
for (int i = 0; i < t.length; i++) {
result[i] = Bytes.toBytes(t[i]);
}
return result;
}
/**
* @param column
* @return A byte array of a byte array where first and only entry is