001/** 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018package org.apache.hadoop.hbase.regionserver; 019 020import static org.junit.Assert.assertEquals; 021import static org.junit.Assert.assertFalse; 022import static org.junit.Assert.assertTrue; 023 024import java.io.IOException; 025import java.util.ArrayList; 026import java.util.List; 027import java.util.concurrent.ThreadLocalRandom; 028import org.apache.hadoop.hbase.Cell; 029import org.apache.hadoop.hbase.HBaseClassTestRule; 030import org.apache.hadoop.hbase.HBaseTestingUtility; 031import org.apache.hadoop.hbase.TableName; 032import org.apache.hadoop.hbase.client.ColumnFamilyDescriptorBuilder; 033import org.apache.hadoop.hbase.client.Put; 034import org.apache.hadoop.hbase.client.Result; 035import org.apache.hadoop.hbase.client.Scan; 036import org.apache.hadoop.hbase.client.TableDescriptorBuilder; 037import org.apache.hadoop.hbase.regionserver.HRegion.RegionScannerImpl; 038import org.apache.hadoop.hbase.testclassification.MediumTests; 039import org.apache.hadoop.hbase.testclassification.RegionServerTests; 040import org.apache.hadoop.hbase.util.Bytes; 041import org.junit.AfterClass; 042import org.junit.BeforeClass; 043import org.junit.ClassRule; 044import org.junit.Test; 045import org.junit.experimental.categories.Category; 046 047@Category({ RegionServerTests.class, MediumTests.class }) 048public class TestSwitchToStreamRead { 049 050 @ClassRule 051 public static final HBaseClassTestRule CLASS_RULE = 052 HBaseClassTestRule.forClass(TestSwitchToStreamRead.class); 053 054 private static final HBaseTestingUtility UTIL = new HBaseTestingUtility(); 055 056 private static TableName TABLE_NAME = TableName.valueOf("stream"); 057 058 private static byte[] FAMILY = Bytes.toBytes("cf"); 059 060 private static byte[] QUAL = Bytes.toBytes("cq"); 061 062 private static String VALUE_PREFIX; 063 064 private static HRegion REGION; 065 066 @BeforeClass 067 public static void setUp() throws IOException { 068 UTIL.getConfiguration().setLong(StoreScanner.STORESCANNER_PREAD_MAX_BYTES, 2048); 069 StringBuilder sb = new StringBuilder(256); 070 for (int i = 0; i < 255; i++) { 071 sb.append((char) ThreadLocalRandom.current().nextInt('A', 'z' + 1)); 072 } 073 VALUE_PREFIX = sb.append("-").toString(); 074 REGION = UTIL.createLocalHRegion( 075 TableDescriptorBuilder.newBuilder(TABLE_NAME) 076 .setColumnFamily( 077 ColumnFamilyDescriptorBuilder.newBuilder(FAMILY).setBlocksize(1024).build()) 078 .build(), 079 null, null); 080 for (int i = 0; i < 900; i++) { 081 REGION 082 .put(new Put(Bytes.toBytes(i)).addColumn(FAMILY, QUAL, Bytes.toBytes(VALUE_PREFIX + i))); 083 } 084 REGION.flush(true); 085 for (int i = 900; i < 1000; i++) { 086 REGION 087 .put(new Put(Bytes.toBytes(i)).addColumn(FAMILY, QUAL, Bytes.toBytes(VALUE_PREFIX + i))); 088 } 089 } 090 091 @AfterClass 092 public static void tearDown() throws IOException { 093 REGION.close(true); 094 UTIL.cleanupTestDir(); 095 } 096 097 @Test 098 public void test() throws IOException { 099 try (RegionScannerImpl scanner = REGION.getScanner(new Scan())) { 100 StoreScanner storeScanner = (StoreScanner) (scanner) 101 .getStoreHeapForTesting().getCurrentForTesting(); 102 for (KeyValueScanner kvs : storeScanner.getAllScannersForTesting()) { 103 if (kvs instanceof StoreFileScanner) { 104 StoreFileScanner sfScanner = (StoreFileScanner) kvs; 105 // starting from pread so we use shared reader here. 106 assertTrue(sfScanner.getReader().shared); 107 } 108 } 109 List<Cell> cells = new ArrayList<>(); 110 for (int i = 0; i < 500; i++) { 111 assertTrue(scanner.next(cells)); 112 Result result = Result.create(cells); 113 assertEquals(VALUE_PREFIX + i, Bytes.toString(result.getValue(FAMILY, QUAL))); 114 cells.clear(); 115 scanner.shipped(); 116 } 117 for (KeyValueScanner kvs : storeScanner.getAllScannersForTesting()) { 118 if (kvs instanceof StoreFileScanner) { 119 StoreFileScanner sfScanner = (StoreFileScanner) kvs; 120 // we should have convert to use stream read now. 121 assertFalse(sfScanner.getReader().shared); 122 } 123 } 124 for (int i = 500; i < 1000; i++) { 125 assertEquals(i != 999, scanner.next(cells)); 126 Result result = Result.create(cells); 127 assertEquals(VALUE_PREFIX + i, Bytes.toString(result.getValue(FAMILY, QUAL))); 128 cells.clear(); 129 scanner.shipped(); 130 } 131 } 132 // make sure all scanners are closed. 133 for (HStoreFile sf : REGION.getStore(FAMILY).getStorefiles()) { 134 assertFalse(sf.isReferencedInReads()); 135 } 136 } 137}