Index: src/contrib/hbase/src/java/org/apache/hadoop/hbase/HRegionInterface.java =================================================================== --- src/contrib/hbase/src/java/org/apache/hadoop/hbase/HRegionInterface.java (revision 597251) +++ src/contrib/hbase/src/java/org/apache/hadoop/hbase/HRegionInterface.java (working copy) @@ -100,6 +100,18 @@ throws IOException; /** + * Get all the data for the specified row at a given timestamp + * + * @param regionName region name + * @param row row key + * @return map of values + * @throws IOException + */ + public MapWritable getRow(final Text regionName, final Text row, final long ts) + throws IOException; + + + /** * Applies a batch of updates via one RPC * * @param regionName name of the region to update Index: src/contrib/hbase/src/java/org/apache/hadoop/hbase/HRegionServer.java =================================================================== --- src/contrib/hbase/src/java/org/apache/hadoop/hbase/HRegionServer.java (revision 597251) +++ src/contrib/hbase/src/java/org/apache/hadoop/hbase/HRegionServer.java (working copy) @@ -1059,6 +1059,29 @@ } /** {@inheritDoc} */ + public MapWritable getRow(final Text regionName, final Text row, final long ts) + throws IOException { + + checkOpen(); + requestCount.incrementAndGet(); + try { + HRegion region = getRegion(regionName); + MapWritable result = new MapWritable(); + Map map = region.getFull(row); + for (Map.Entry es: map.entrySet()) { + result.put(new HStoreKey(row, es.getKey()), + new ImmutableBytesWritable(es.getValue())); + } + return result; + + } catch (IOException e) { + checkFileSystem(); + throw e; + } + } + + + /** {@inheritDoc} */ public MapWritable next(final long scannerId) throws IOException { checkOpen(); Index: src/contrib/hbase/src/java/org/apache/hadoop/hbase/HRegion.java =================================================================== --- src/contrib/hbase/src/java/org/apache/hadoop/hbase/HRegion.java (revision 597251) +++ src/contrib/hbase/src/java/org/apache/hadoop/hbase/HRegion.java (working copy) @@ -1025,7 +1025,25 @@ * @throws IOException */ public Map getFull(Text row) throws IOException { - HStoreKey key = new HStoreKey(row, System.currentTimeMillis()); + return getFull(row, HConstants.LATEST_TIMESTAMP); + } + + /** + * Fetch all the columns for the indicated row at a specified timestamp. + * Returns a TreeMap that maps column names to values. + * + * We should eventually use Bloom filters here, to reduce running time. If + * the database has many column families and is very sparse, then we could be + * checking many files needlessly. A small Bloom for each row would help us + * determine which column groups are useful for that row. That would let us + * avoid a bunch of disk activity. + * + * @param row + * @return Map values + * @throws IOException + */ + public Map getFull(Text row, long ts) throws IOException { + HStoreKey key = new HStoreKey(row, ts); obtainRowLock(row); try { TreeMap result = new TreeMap(); Index: src/contrib/hbase/src/java/org/apache/hadoop/hbase/HTable.java =================================================================== --- src/contrib/hbase/src/java/org/apache/hadoop/hbase/HTable.java (revision 597251) +++ src/contrib/hbase/src/java/org/apache/hadoop/hbase/HTable.java (working copy) @@ -324,13 +324,24 @@ } /** - * Get all the data for the specified row + * Get all the data for the specified row at the latest timestamp * * @param row row key * @return map of colums to values * @throws IOException */ public SortedMap getRow(Text row) throws IOException { + return getRow(row, HConstants.LATEST_TIMESTAMP); + } + + /** + * Get all the data for the specified row at a specified timestamp + * + * @param row row key + * @return map of colums to values + * @throws IOException + */ + public SortedMap getRow(Text row, long ts) throws IOException { checkClosed(); MapWritable value = null; for (int tries = 0; tries < numRetries; tries++) { @@ -339,7 +350,7 @@ connection.getHRegionConnection(r.getServerAddress()); try { - value = server.getRow(r.getRegionInfo().getRegionName(), row); + value = server.getRow(r.getRegionInfo().getRegionName(), row, ts); break; } catch (IOException e) { @@ -373,6 +384,7 @@ return results; } + /** * Get a scanner on the current table starting at the specified row. * Return the specified columns.