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