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 */
018
019package org.apache.hadoop.hbase.client;
020
021import java.io.IOException;
022import java.util.ArrayList;
023import java.util.List;
024
025import org.apache.hadoop.conf.Configuration;
026import org.apache.hadoop.fs.FileSystem;
027import org.apache.hadoop.fs.Path;
028import org.apache.hadoop.hbase.Cell;
029import org.apache.hadoop.hbase.PrivateCellUtil;
030import org.apache.hadoop.hbase.client.metrics.ScanMetrics;
031import org.apache.hadoop.hbase.regionserver.HRegion;
032import org.apache.hadoop.hbase.regionserver.RegionScanner;
033import org.apache.yetus.audience.InterfaceAudience;
034import org.slf4j.Logger;
035import org.slf4j.LoggerFactory;
036
037/**
038 * A client scanner for a region opened for read-only on the client side. Assumes region data
039 * is not changing.
040 */
041@InterfaceAudience.Private
042public class ClientSideRegionScanner extends AbstractClientScanner {
043
044  private static final Logger LOG = LoggerFactory.getLogger(ClientSideRegionScanner.class);
045
046  private HRegion region;
047  RegionScanner scanner;
048  List<Cell> values;
049
050  public ClientSideRegionScanner(Configuration conf, FileSystem fs,
051      Path rootDir, TableDescriptor htd, RegionInfo hri, Scan scan, ScanMetrics scanMetrics)
052          throws IOException {
053    // region is immutable, set isolation level
054    scan.setIsolationLevel(IsolationLevel.READ_UNCOMMITTED);
055
056    htd = TableDescriptorBuilder.newBuilder(htd).setReadOnly(true).build();
057
058    // open region from the snapshot directory
059    this.region = HRegion.openHRegion(conf, fs, rootDir, hri, htd, null, null, null);
060
061    // create an internal region scanner
062    this.scanner = region.getScanner(scan);
063    values = new ArrayList<>();
064
065    if (scanMetrics == null) {
066      initScanMetrics(scan);
067    } else {
068      this.scanMetrics = scanMetrics;
069    }
070    region.startRegionOperation();
071  }
072
073  @Override
074  public Result next() throws IOException {
075    values.clear();
076    scanner.nextRaw(values);
077    if (values.isEmpty()) {
078      //we are done
079      return null;
080    }
081
082    Result result = Result.create(values);
083    if (this.scanMetrics != null) {
084      long resultSize = 0;
085      for (Cell cell : values) {
086        resultSize += PrivateCellUtil.estimatedSerializedSizeOf(cell);
087      }
088      this.scanMetrics.countOfBytesInResults.addAndGet(resultSize);
089      this.scanMetrics.countOfRowsScanned.incrementAndGet();
090    }
091
092    return result;
093  }
094
095  @Override
096  public void close() {
097    if (this.scanner != null) {
098      try {
099        this.scanner.close();
100        this.scanner = null;
101      } catch (IOException ex) {
102        LOG.warn("Exception while closing scanner", ex);
103      }
104    }
105    if (this.region != null) {
106      try {
107        this.region.closeRegionOperation();
108        this.region.close(true);
109        this.region = null;
110      } catch (IOException ex) {
111        LOG.warn("Exception while closing region", ex);
112      }
113    }
114  }
115
116  @Override
117  public boolean renewLease() {
118    throw new UnsupportedOperationException();
119  }
120}