001/** 002 * 003 * Licensed to the Apache Software Foundation (ASF) under one 004 * or more contributor license agreements. See the NOTICE file 005 * distributed with this work for additional information 006 * regarding copyright ownership. The ASF licenses this file 007 * to you under the Apache License, Version 2.0 (the 008 * "License"); you may not use this file except in compliance 009 * with the License. You may obtain a copy of the License at 010 * 011 * http://www.apache.org/licenses/LICENSE-2.0 012 * 013 * Unless required by applicable law or agreed to in writing, software 014 * distributed under the License is distributed on an "AS IS" BASIS, 015 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 016 * See the License for the specific language governing permissions and 017 * limitations under the License. 018 */ 019package org.apache.hadoop.hbase.regionserver; 020 021import java.io.IOException; 022import java.util.List; 023import java.util.NavigableSet; 024 025import org.apache.hadoop.hbase.Cell; 026import org.apache.hadoop.hbase.client.Scan; 027import org.apache.hadoop.hbase.mob.MobUtils; 028import org.apache.yetus.audience.InterfaceAudience; 029 030/** 031 * Scanner scans both the memstore and the MOB Store. Coalesce KeyValue stream into 032 * {@code List<KeyValue>} for a single row. 033 */ 034@InterfaceAudience.Private 035public class MobStoreScanner extends StoreScanner { 036 037 private boolean cacheMobBlocks = false; 038 private boolean rawMobScan = false; 039 private boolean readEmptyValueOnMobCellMiss = false; 040 private final HMobStore mobStore; 041 042 public MobStoreScanner(HStore store, ScanInfo scanInfo, Scan scan, 043 final NavigableSet<byte[]> columns, long readPt) throws IOException { 044 super(store, scanInfo, scan, columns, readPt); 045 cacheMobBlocks = MobUtils.isCacheMobBlocks(scan); 046 rawMobScan = MobUtils.isRawMobScan(scan); 047 readEmptyValueOnMobCellMiss = MobUtils.isReadEmptyValueOnMobCellMiss(scan); 048 if (!(store instanceof HMobStore)) { 049 throw new IllegalArgumentException("The store " + store + " is not a HMobStore"); 050 } 051 mobStore = (HMobStore) store; 052 } 053 054 /** 055 * Firstly reads the cells from the HBase. If the cell are a reference cell (which has the 056 * reference tag), the scanner need seek this cell from the mob file, and use the cell found 057 * from the mob file as the result. 058 */ 059 @Override 060 public boolean next(List<Cell> outResult, ScannerContext ctx) throws IOException { 061 boolean result = super.next(outResult, ctx); 062 if (!rawMobScan) { 063 // retrieve the mob data 064 if (outResult.isEmpty()) { 065 return result; 066 } 067 long mobKVCount = 0; 068 long mobKVSize = 0; 069 for (int i = 0; i < outResult.size(); i++) { 070 Cell cell = outResult.get(i); 071 if (MobUtils.isMobReferenceCell(cell)) { 072 Cell mobCell = mobStore 073 .resolve(cell, cacheMobBlocks, readPt, readEmptyValueOnMobCellMiss); 074 mobKVCount++; 075 mobKVSize += mobCell.getValueLength(); 076 outResult.set(i, mobCell); 077 } 078 } 079 mobStore.updateMobScanCellsCount(mobKVCount); 080 mobStore.updateMobScanCellsSize(mobKVSize); 081 } 082 return result; 083 } 084}