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