| /** |
| * 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 org.apache.hadoop.fs.Path; |
| import org.apache.hadoop.hbase.client.Get; |
| import org.apache.hadoop.hbase.client.HTable; |
| 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.client.ResultScanner; |
| import org.apache.hadoop.hbase.regionserver.HRegion; |
| import org.apache.hadoop.hbase.util.Bytes; |
| |
| /** |
| * Regression test for HBASE-613 |
| */ |
| public class TestScanMultipleVersions extends HBaseClusterTestCase { |
| private final byte[] TABLE_NAME = Bytes.toBytes("TestScanMultipleVersions"); |
| private final HRegionInfo[] INFOS = new HRegionInfo[2]; |
| private final HRegion[] REGIONS = new HRegion[2]; |
| private final byte[][] ROWS = new byte[][] { |
| Bytes.toBytes("row_0200"), |
| Bytes.toBytes("row_0800") |
| }; |
| private final long[] TIMESTAMPS = new long[] { |
| 100L, |
| 1000L |
| }; |
| private HTableDescriptor desc = null; |
| |
| @Override |
| protected void preHBaseClusterSetup() throws Exception { |
| testDir = new Path(conf.get(HConstants.HBASE_DIR)); |
| |
| // Create table description |
| |
| this.desc = new HTableDescriptor(TABLE_NAME); |
| this.desc.addFamily(new HColumnDescriptor(HConstants.CATALOG_FAMILY)); |
| |
| // Region 0 will contain the key range [,row_0500) |
| INFOS[0] = new HRegionInfo(this.desc, HConstants.EMPTY_START_ROW, |
| Bytes.toBytes("row_0500")); |
| // Region 1 will contain the key range [row_0500,) |
| INFOS[1] = new HRegionInfo(this.desc, Bytes.toBytes("row_0500"), |
| HConstants.EMPTY_END_ROW); |
| |
| // Create root and meta regions |
| createRootAndMetaRegions(); |
| // Create the regions |
| for (int i = 0; i < REGIONS.length; i++) { |
| REGIONS[i] = |
| HRegion.createHRegion(this.INFOS[i], this.testDir, this.conf); |
| // Insert data |
| for (int j = 0; j < TIMESTAMPS.length; j++) { |
| Put put = new Put(ROWS[i], TIMESTAMPS[j], null); |
| put.add(HConstants.CATALOG_FAMILY, null, TIMESTAMPS[j], |
| Bytes.toBytes(TIMESTAMPS[j])); |
| REGIONS[i].put(put); |
| } |
| // Insert the region we created into the meta |
| HRegion.addRegionToMETA(meta, REGIONS[i]); |
| // Close region |
| REGIONS[i].close(); |
| REGIONS[i].getLog().closeAndDelete(); |
| } |
| // Close root and meta regions |
| closeRootAndMeta(); |
| } |
| |
| /** |
| * @throws Exception |
| */ |
| public void testScanMultipleVersions() throws Exception { |
| // At this point we have created multiple regions and both HDFS and HBase |
| // are running. There are 5 cases we have to test. Each is described below. |
| HTable t = new HTable(conf, TABLE_NAME); |
| for (int i = 0; i < ROWS.length; i++) { |
| for (int j = 0; j < TIMESTAMPS.length; j++) { |
| Get get = new Get(ROWS[i]); |
| get.addFamily(HConstants.CATALOG_FAMILY); |
| get.setTimeStamp(TIMESTAMPS[j]); |
| Result result = t.get(get); |
| int cellCount = 0; |
| for(@SuppressWarnings("unused")KeyValue kv : result.sorted()) { |
| cellCount++; |
| } |
| assertTrue(cellCount == 1); |
| } |
| } |
| |
| // Case 1: scan with LATEST_TIMESTAMP. Should get two rows |
| int count = 0; |
| Scan scan = new Scan(); |
| scan.addFamily(HConstants.CATALOG_FAMILY); |
| ResultScanner s = t.getScanner(scan); |
| try { |
| for (Result rr = null; (rr = s.next()) != null;) { |
| System.out.println(rr.toString()); |
| count += 1; |
| } |
| assertEquals("Number of rows should be 2", 2, count); |
| } finally { |
| s.close(); |
| } |
| |
| // Case 2: Scan with a timestamp greater than most recent timestamp |
| // (in this case > 1000 and < LATEST_TIMESTAMP. Should get 2 rows. |
| |
| count = 0; |
| scan = new Scan(); |
| scan.setTimeRange(1000L, Long.MAX_VALUE); |
| scan.addFamily(HConstants.CATALOG_FAMILY); |
| |
| s = t.getScanner(scan); |
| try { |
| while (s.next() != null) { |
| count += 1; |
| } |
| assertEquals("Number of rows should be 2", 2, count); |
| } finally { |
| s.close(); |
| } |
| |
| // Case 3: scan with timestamp equal to most recent timestamp |
| // (in this case == 1000. Should get 2 rows. |
| |
| count = 0; |
| scan = new Scan(); |
| scan.setTimeStamp(1000L); |
| scan.addFamily(HConstants.CATALOG_FAMILY); |
| |
| s = t.getScanner(scan); |
| try { |
| while (s.next() != null) { |
| count += 1; |
| } |
| assertEquals("Number of rows should be 2", 2, count); |
| } finally { |
| s.close(); |
| } |
| |
| // Case 4: scan with timestamp greater than first timestamp but less than |
| // second timestamp (100 < timestamp < 1000). Should get 2 rows. |
| |
| count = 0; |
| scan = new Scan(); |
| scan.setTimeRange(100L, 1000L); |
| scan.addFamily(HConstants.CATALOG_FAMILY); |
| |
| s = t.getScanner(scan); |
| try { |
| while (s.next() != null) { |
| count += 1; |
| } |
| assertEquals("Number of rows should be 2", 2, count); |
| } finally { |
| s.close(); |
| } |
| |
| // Case 5: scan with timestamp equal to first timestamp (100) |
| // Should get 2 rows. |
| |
| count = 0; |
| scan = new Scan(); |
| scan.setTimeStamp(100L); |
| scan.addFamily(HConstants.CATALOG_FAMILY); |
| |
| s = t.getScanner(scan); |
| try { |
| while (s.next() != null) { |
| count += 1; |
| } |
| assertEquals("Number of rows should be 2", 2, count); |
| } finally { |
| s.close(); |
| } |
| } |
| } |