View Javadoc

1   /**
2    *
3    * Licensed to the Apache Software Foundation (ASF) under one
4    * or more contributor license agreements.  See the NOTICE file
5    * distributed with this work for additional information
6    * regarding copyright ownership.  The ASF licenses this file
7    * to you under the Apache License, Version 2.0 (the
8    * "License"); you may not use this file except in compliance
9    * with the License.  You may obtain a copy of the License at
10   *
11   *     http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing, software
14   * distributed under the License is distributed on an "AS IS" BASIS,
15   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16   * See the License for the specific language governing permissions and
17   * limitations under the License.
18   */
19  package org.apache.hadoop.hbase.regionserver;
20  
21  import java.io.IOException;
22  import java.util.List;
23  import java.util.NavigableSet;
24  
25  import org.apache.hadoop.hbase.classification.InterfaceAudience;
26  import org.apache.hadoop.hbase.Cell;
27  import org.apache.hadoop.hbase.client.Scan;
28  import org.apache.hadoop.hbase.mob.MobUtils;
29  
30  /**
31   * Scanner scans both the memstore and the MOB Store. Coalesce KeyValue stream into List<KeyValue>
32   * for a single row.
33   *
34   */
35  @InterfaceAudience.Private
36  public class MobStoreScanner extends StoreScanner {
37  
38    private boolean cacheMobBlocks = false;
39    private boolean rawMobScan = false;
40    private boolean readEmptyValueOnMobCellMiss = false;
41    private final HMobStore mobStore;
42  
43    public MobStoreScanner(Store store, ScanInfo scanInfo, Scan scan,
44        final NavigableSet<byte[]> columns, long readPt) throws IOException {
45      super(store, scanInfo, scan, columns, readPt);
46      cacheMobBlocks = MobUtils.isCacheMobBlocks(scan);
47      rawMobScan = MobUtils.isRawMobScan(scan);
48      readEmptyValueOnMobCellMiss = MobUtils.isReadEmptyValueOnMobCellMiss(scan);
49      if (!(store instanceof HMobStore)) {
50        throw new IllegalArgumentException("The store " + store + " is not a HMobStore");
51      }
52      mobStore = (HMobStore) store;
53    }
54  
55    /**
56     * Firstly reads the cells from the HBase. If the cell are a reference cell (which has the
57     * reference tag), the scanner need seek this cell from the mob file, and use the cell found
58     * from the mob file as the result.
59     */
60    @Override
61    public boolean next(List<Cell> outResult, ScannerContext ctx) throws IOException {
62      boolean result = super.next(outResult, ctx);
63      if (!rawMobScan) {
64        // retrieve the mob data
65        if (outResult.isEmpty()) {
66          return result;
67        }
68        long mobKVCount = 0;
69        long mobKVSize = 0;
70        for (int i = 0; i < outResult.size(); i++) {
71          Cell cell = outResult.get(i);
72          if (MobUtils.isMobReferenceCell(cell)) {
73            Cell mobCell = mobStore
74              .resolve(cell, cacheMobBlocks, readPt, readEmptyValueOnMobCellMiss);
75            mobKVCount++;
76            mobKVSize += mobCell.getValueLength();
77            outResult.set(i, mobCell);
78          }
79        }
80        mobStore.updateMobScanCellsCount(mobKVCount);
81        mobStore.updateMobScanCellsSize(mobKVSize);
82      }
83      return result;
84    }
85  }