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 * ReversedMobStoreScanner extends from ReversedStoreScanner, and is used to support 032 * reversed scanning in both the memstore and the MOB store. 033 * 034 */ 035@InterfaceAudience.Private 036public class ReversedMobStoreScanner extends ReversedStoreScanner { 037 038 private boolean cacheMobBlocks = false; 039 private boolean rawMobScan = false; 040 private boolean readEmptyValueOnMobCellMiss = false; 041 protected final HMobStore mobStore; 042 043 ReversedMobStoreScanner(HStore store, ScanInfo scanInfo, Scan scan, NavigableSet<byte[]> columns, 044 long readPt) throws IOException { 045 super(store, scanInfo, scan, columns, readPt); 046 cacheMobBlocks = MobUtils.isCacheMobBlocks(scan); 047 rawMobScan = MobUtils.isRawMobScan(scan); 048 readEmptyValueOnMobCellMiss = MobUtils.isReadEmptyValueOnMobCellMiss(scan); 049 if (!(store instanceof HMobStore)) { 050 throw new IllegalArgumentException("The store " + store + " is not a HMobStore"); 051 } 052 mobStore = (HMobStore) store; 053 } 054 055 /** 056 * Firstly reads the cells from the HBase. If the cell is a reference cell (which has the 057 * reference tag), the scanner need seek this cell from the mob file, and use the cell found 058 * from the mob file as the result. 059 */ 060 @Override 061 public boolean next(List<Cell> outResult, ScannerContext ctx) throws IOException { 062 boolean result = super.next(outResult, ctx); 063 if (!rawMobScan) { 064 // retrieve the mob data 065 if (outResult.isEmpty()) { 066 return result; 067 } 068 long mobKVCount = 0; 069 long mobKVSize = 0; 070 for (int i = 0; i < outResult.size(); i++) { 071 Cell cell = outResult.get(i); 072 if (MobUtils.isMobReferenceCell(cell)) { 073 Cell mobCell = mobStore 074 .resolve(cell, cacheMobBlocks, readPt, readEmptyValueOnMobCellMiss); 075 mobKVCount++; 076 mobKVSize += mobCell.getValueLength(); 077 outResult.set(i, mobCell); 078 } 079 } 080 mobStore.updateMobScanCellsCount(mobKVCount); 081 mobStore.updateMobScanCellsSize(mobKVSize); 082 } 083 return result; 084 } 085}