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 */ 018package org.apache.hadoop.hbase.regionserver.querymatcher; 019 020import java.io.IOException; 021 022import org.apache.hadoop.hbase.Cell; 023import org.apache.hadoop.hbase.CellUtil; 024import org.apache.hadoop.hbase.PrivateCellUtil; 025import org.apache.hadoop.hbase.KeepDeletedCells; 026import org.apache.yetus.audience.InterfaceAudience; 027import org.apache.hadoop.hbase.client.Scan; 028import org.apache.hadoop.hbase.regionserver.ScanInfo; 029 030/** 031 * Query matcher for normal user scan. 032 */ 033@InterfaceAudience.Private 034public abstract class NormalUserScanQueryMatcher extends UserScanQueryMatcher { 035 036 /** Keeps track of deletes */ 037 private final DeleteTracker deletes; 038 039 /** True if we are doing a 'Get' Scan. Every Get is actually a one-row Scan. */ 040 private final boolean get; 041 042 /** whether time range queries can see rows "behind" a delete */ 043 protected final boolean seePastDeleteMarkers; 044 045 protected NormalUserScanQueryMatcher(Scan scan, ScanInfo scanInfo, ColumnTracker columns, 046 boolean hasNullColumn, DeleteTracker deletes, long oldestUnexpiredTS, long now) { 047 super(scan, scanInfo, columns, hasNullColumn, oldestUnexpiredTS, now); 048 this.deletes = deletes; 049 this.get = scan.isGetScan(); 050 this.seePastDeleteMarkers = scanInfo.getKeepDeletedCells() != KeepDeletedCells.FALSE; 051 } 052 053 @Override 054 public void beforeShipped() throws IOException { 055 super.beforeShipped(); 056 deletes.beforeShipped(); 057 } 058 059 @Override 060 public MatchCode match(Cell cell) throws IOException { 061 if (filter != null && filter.filterAllRemaining()) { 062 return MatchCode.DONE_SCAN; 063 } 064 MatchCode returnCode = preCheck(cell); 065 if (returnCode != null) { 066 return returnCode; 067 } 068 long timestamp = cell.getTimestamp(); 069 byte typeByte = cell.getTypeByte(); 070 if (PrivateCellUtil.isDelete(typeByte)) { 071 boolean includeDeleteMarker = seePastDeleteMarkers ? tr.withinTimeRange(timestamp) 072 : tr.withinOrAfterTimeRange(timestamp); 073 if (includeDeleteMarker) { 074 this.deletes.add(cell); 075 } 076 return MatchCode.SKIP; 077 } 078 returnCode = checkDeleted(deletes, cell); 079 if (returnCode != null) { 080 return returnCode; 081 } 082 return matchColumn(cell, timestamp, typeByte); 083 } 084 085 @Override 086 protected void reset() { 087 deletes.reset(); 088 } 089 090 @Override 091 protected boolean isGet() { 092 return get; 093 } 094 095 public static NormalUserScanQueryMatcher create(Scan scan, ScanInfo scanInfo, 096 ColumnTracker columns, DeleteTracker deletes, boolean hasNullColumn, long oldestUnexpiredTS, 097 long now) throws IOException { 098 if (scan.isReversed()) { 099 if (scan.includeStopRow()) { 100 return new NormalUserScanQueryMatcher(scan, scanInfo, columns, hasNullColumn, deletes, 101 oldestUnexpiredTS, now) { 102 103 @Override 104 protected boolean moreRowsMayExistsAfter(int cmpToStopRow) { 105 return cmpToStopRow >= 0; 106 } 107 }; 108 } else { 109 return new NormalUserScanQueryMatcher(scan, scanInfo, columns, hasNullColumn, deletes, 110 oldestUnexpiredTS, now) { 111 112 @Override 113 protected boolean moreRowsMayExistsAfter(int cmpToStopRow) { 114 return cmpToStopRow > 0; 115 } 116 }; 117 } 118 } else { 119 if (scan.includeStopRow()) { 120 return new NormalUserScanQueryMatcher(scan, scanInfo, columns, hasNullColumn, deletes, 121 oldestUnexpiredTS, now) { 122 123 @Override 124 protected boolean moreRowsMayExistsAfter(int cmpToStopRow) { 125 return cmpToStopRow <= 0; 126 } 127 }; 128 } else { 129 return new NormalUserScanQueryMatcher(scan, scanInfo, columns, hasNullColumn, deletes, 130 oldestUnexpiredTS, now) { 131 132 @Override 133 protected boolean moreRowsMayExistsAfter(int cmpToStopRow) { 134 return cmpToStopRow < 0; 135 } 136 }; 137 } 138 } 139 } 140}