blob: 46212a588639286da879dde81360dbdd8b7f1a2b [file] [log] [blame]
<!DOCTYPE HTML>
<html lang="en">
<head>
<!-- Generated by javadoc (17) -->
<title>Source code</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="source: package: org.apache.hadoop.hbase.regionserver, class: TestHRegion, class: NoOpRegionCoprocessor">
<meta name="generator" content="javadoc/SourceToHTMLConverter">
<link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style">
</head>
<body class="source-page">
<main role="main">
<div class="source-container">
<pre><span class="source-line-no">001</span><span id="line-1">/*</span>
<span class="source-line-no">002</span><span id="line-2"> * Licensed to the Apache Software Foundation (ASF) under one</span>
<span class="source-line-no">003</span><span id="line-3"> * or more contributor license agreements. See the NOTICE file</span>
<span class="source-line-no">004</span><span id="line-4"> * distributed with this work for additional information</span>
<span class="source-line-no">005</span><span id="line-5"> * regarding copyright ownership. The ASF licenses this file</span>
<span class="source-line-no">006</span><span id="line-6"> * to you under the Apache License, Version 2.0 (the</span>
<span class="source-line-no">007</span><span id="line-7"> * "License"); you may not use this file except in compliance</span>
<span class="source-line-no">008</span><span id="line-8"> * with the License. You may obtain a copy of the License at</span>
<span class="source-line-no">009</span><span id="line-9"> *</span>
<span class="source-line-no">010</span><span id="line-10"> * http://www.apache.org/licenses/LICENSE-2.0</span>
<span class="source-line-no">011</span><span id="line-11"> *</span>
<span class="source-line-no">012</span><span id="line-12"> * Unless required by applicable law or agreed to in writing, software</span>
<span class="source-line-no">013</span><span id="line-13"> * distributed under the License is distributed on an "AS IS" BASIS,</span>
<span class="source-line-no">014</span><span id="line-14"> * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.</span>
<span class="source-line-no">015</span><span id="line-15"> * See the License for the specific language governing permissions and</span>
<span class="source-line-no">016</span><span id="line-16"> * limitations under the License.</span>
<span class="source-line-no">017</span><span id="line-17"> */</span>
<span class="source-line-no">018</span><span id="line-18">package org.apache.hadoop.hbase.regionserver;</span>
<span class="source-line-no">019</span><span id="line-19"></span>
<span class="source-line-no">020</span><span id="line-20">import static org.apache.hadoop.hbase.HBaseTestingUtil.COLUMNS;</span>
<span class="source-line-no">021</span><span id="line-21">import static org.apache.hadoop.hbase.HBaseTestingUtil.fam1;</span>
<span class="source-line-no">022</span><span id="line-22">import static org.apache.hadoop.hbase.HBaseTestingUtil.fam2;</span>
<span class="source-line-no">023</span><span id="line-23">import static org.apache.hadoop.hbase.HBaseTestingUtil.fam3;</span>
<span class="source-line-no">024</span><span id="line-24">import static org.junit.Assert.assertArrayEquals;</span>
<span class="source-line-no">025</span><span id="line-25">import static org.junit.Assert.assertEquals;</span>
<span class="source-line-no">026</span><span id="line-26">import static org.junit.Assert.assertFalse;</span>
<span class="source-line-no">027</span><span id="line-27">import static org.junit.Assert.assertNotNull;</span>
<span class="source-line-no">028</span><span id="line-28">import static org.junit.Assert.assertNull;</span>
<span class="source-line-no">029</span><span id="line-29">import static org.junit.Assert.assertThrows;</span>
<span class="source-line-no">030</span><span id="line-30">import static org.junit.Assert.assertTrue;</span>
<span class="source-line-no">031</span><span id="line-31">import static org.junit.Assert.fail;</span>
<span class="source-line-no">032</span><span id="line-32">import static org.mockito.ArgumentMatchers.any;</span>
<span class="source-line-no">033</span><span id="line-33">import static org.mockito.ArgumentMatchers.anyLong;</span>
<span class="source-line-no">034</span><span id="line-34">import static org.mockito.ArgumentMatchers.anyString;</span>
<span class="source-line-no">035</span><span id="line-35">import static org.mockito.ArgumentMatchers.isA;</span>
<span class="source-line-no">036</span><span id="line-36">import static org.mockito.Mockito.atLeast;</span>
<span class="source-line-no">037</span><span id="line-37">import static org.mockito.Mockito.doAnswer;</span>
<span class="source-line-no">038</span><span id="line-38">import static org.mockito.Mockito.doThrow;</span>
<span class="source-line-no">039</span><span id="line-39">import static org.mockito.Mockito.mock;</span>
<span class="source-line-no">040</span><span id="line-40">import static org.mockito.Mockito.never;</span>
<span class="source-line-no">041</span><span id="line-41">import static org.mockito.Mockito.spy;</span>
<span class="source-line-no">042</span><span id="line-42">import static org.mockito.Mockito.times;</span>
<span class="source-line-no">043</span><span id="line-43">import static org.mockito.Mockito.verify;</span>
<span class="source-line-no">044</span><span id="line-44">import static org.mockito.Mockito.when;</span>
<span class="source-line-no">045</span><span id="line-45"></span>
<span class="source-line-no">046</span><span id="line-46">import java.io.IOException;</span>
<span class="source-line-no">047</span><span id="line-47">import java.io.InterruptedIOException;</span>
<span class="source-line-no">048</span><span id="line-48">import java.math.BigDecimal;</span>
<span class="source-line-no">049</span><span id="line-49">import java.security.PrivilegedExceptionAction;</span>
<span class="source-line-no">050</span><span id="line-50">import java.util.ArrayList;</span>
<span class="source-line-no">051</span><span id="line-51">import java.util.Arrays;</span>
<span class="source-line-no">052</span><span id="line-52">import java.util.Collection;</span>
<span class="source-line-no">053</span><span id="line-53">import java.util.List;</span>
<span class="source-line-no">054</span><span id="line-54">import java.util.Map;</span>
<span class="source-line-no">055</span><span id="line-55">import java.util.NavigableMap;</span>
<span class="source-line-no">056</span><span id="line-56">import java.util.Objects;</span>
<span class="source-line-no">057</span><span id="line-57">import java.util.Set;</span>
<span class="source-line-no">058</span><span id="line-58">import java.util.TreeMap;</span>
<span class="source-line-no">059</span><span id="line-59">import java.util.concurrent.Callable;</span>
<span class="source-line-no">060</span><span id="line-60">import java.util.concurrent.CountDownLatch;</span>
<span class="source-line-no">061</span><span id="line-61">import java.util.concurrent.ExecutorService;</span>
<span class="source-line-no">062</span><span id="line-62">import java.util.concurrent.Executors;</span>
<span class="source-line-no">063</span><span id="line-63">import java.util.concurrent.Future;</span>
<span class="source-line-no">064</span><span id="line-64">import java.util.concurrent.TimeUnit;</span>
<span class="source-line-no">065</span><span id="line-65">import java.util.concurrent.atomic.AtomicBoolean;</span>
<span class="source-line-no">066</span><span id="line-66">import java.util.concurrent.atomic.AtomicInteger;</span>
<span class="source-line-no">067</span><span id="line-67">import java.util.concurrent.atomic.AtomicLong;</span>
<span class="source-line-no">068</span><span id="line-68">import java.util.concurrent.atomic.AtomicReference;</span>
<span class="source-line-no">069</span><span id="line-69">import org.apache.commons.lang3.RandomStringUtils;</span>
<span class="source-line-no">070</span><span id="line-70">import org.apache.hadoop.conf.Configuration;</span>
<span class="source-line-no">071</span><span id="line-71">import org.apache.hadoop.fs.FSDataOutputStream;</span>
<span class="source-line-no">072</span><span id="line-72">import org.apache.hadoop.fs.FileStatus;</span>
<span class="source-line-no">073</span><span id="line-73">import org.apache.hadoop.fs.FileSystem;</span>
<span class="source-line-no">074</span><span id="line-74">import org.apache.hadoop.fs.Path;</span>
<span class="source-line-no">075</span><span id="line-75">import org.apache.hadoop.hbase.ArrayBackedTag;</span>
<span class="source-line-no">076</span><span id="line-76">import org.apache.hadoop.hbase.Cell;</span>
<span class="source-line-no">077</span><span id="line-77">import org.apache.hadoop.hbase.Cell.Type;</span>
<span class="source-line-no">078</span><span id="line-78">import org.apache.hadoop.hbase.CellBuilderFactory;</span>
<span class="source-line-no">079</span><span id="line-79">import org.apache.hadoop.hbase.CellBuilderType;</span>
<span class="source-line-no">080</span><span id="line-80">import org.apache.hadoop.hbase.CellUtil;</span>
<span class="source-line-no">081</span><span id="line-81">import org.apache.hadoop.hbase.CompareOperator;</span>
<span class="source-line-no">082</span><span id="line-82">import org.apache.hadoop.hbase.CompatibilitySingletonFactory;</span>
<span class="source-line-no">083</span><span id="line-83">import org.apache.hadoop.hbase.DoNotRetryIOException;</span>
<span class="source-line-no">084</span><span id="line-84">import org.apache.hadoop.hbase.DroppedSnapshotException;</span>
<span class="source-line-no">085</span><span id="line-85">import org.apache.hadoop.hbase.ExtendedCell;</span>
<span class="source-line-no">086</span><span id="line-86">import org.apache.hadoop.hbase.ExtendedCellBuilderFactory;</span>
<span class="source-line-no">087</span><span id="line-87">import org.apache.hadoop.hbase.HBaseClassTestRule;</span>
<span class="source-line-no">088</span><span id="line-88">import org.apache.hadoop.hbase.HBaseConfiguration;</span>
<span class="source-line-no">089</span><span id="line-89">import org.apache.hadoop.hbase.HBaseTestingUtil;</span>
<span class="source-line-no">090</span><span id="line-90">import org.apache.hadoop.hbase.HConstants;</span>
<span class="source-line-no">091</span><span id="line-91">import org.apache.hadoop.hbase.HConstants.OperationStatusCode;</span>
<span class="source-line-no">092</span><span id="line-92">import org.apache.hadoop.hbase.HDFSBlocksDistribution;</span>
<span class="source-line-no">093</span><span id="line-93">import org.apache.hadoop.hbase.KeyValue;</span>
<span class="source-line-no">094</span><span id="line-94">import org.apache.hadoop.hbase.MultithreadedTestUtil;</span>
<span class="source-line-no">095</span><span id="line-95">import org.apache.hadoop.hbase.MultithreadedTestUtil.RepeatingTestThread;</span>
<span class="source-line-no">096</span><span id="line-96">import org.apache.hadoop.hbase.MultithreadedTestUtil.TestThread;</span>
<span class="source-line-no">097</span><span id="line-97">import org.apache.hadoop.hbase.NotServingRegionException;</span>
<span class="source-line-no">098</span><span id="line-98">import org.apache.hadoop.hbase.PrivateCellUtil;</span>
<span class="source-line-no">099</span><span id="line-99">import org.apache.hadoop.hbase.RegionTooBusyException;</span>
<span class="source-line-no">100</span><span id="line-100">import org.apache.hadoop.hbase.ServerName;</span>
<span class="source-line-no">101</span><span id="line-101">import org.apache.hadoop.hbase.SingleProcessHBaseCluster;</span>
<span class="source-line-no">102</span><span id="line-102">import org.apache.hadoop.hbase.StartTestingClusterOption;</span>
<span class="source-line-no">103</span><span id="line-103">import org.apache.hadoop.hbase.TableName;</span>
<span class="source-line-no">104</span><span id="line-104">import org.apache.hadoop.hbase.TagType;</span>
<span class="source-line-no">105</span><span id="line-105">import org.apache.hadoop.hbase.Waiter;</span>
<span class="source-line-no">106</span><span id="line-106">import org.apache.hadoop.hbase.client.Append;</span>
<span class="source-line-no">107</span><span id="line-107">import org.apache.hadoop.hbase.client.CheckAndMutate;</span>
<span class="source-line-no">108</span><span id="line-108">import org.apache.hadoop.hbase.client.CheckAndMutateResult;</span>
<span class="source-line-no">109</span><span id="line-109">import org.apache.hadoop.hbase.client.ColumnFamilyDescriptor;</span>
<span class="source-line-no">110</span><span id="line-110">import org.apache.hadoop.hbase.client.ColumnFamilyDescriptorBuilder;</span>
<span class="source-line-no">111</span><span id="line-111">import org.apache.hadoop.hbase.client.Delete;</span>
<span class="source-line-no">112</span><span id="line-112">import org.apache.hadoop.hbase.client.Durability;</span>
<span class="source-line-no">113</span><span id="line-113">import org.apache.hadoop.hbase.client.Get;</span>
<span class="source-line-no">114</span><span id="line-114">import org.apache.hadoop.hbase.client.Increment;</span>
<span class="source-line-no">115</span><span id="line-115">import org.apache.hadoop.hbase.client.Mutation;</span>
<span class="source-line-no">116</span><span id="line-116">import org.apache.hadoop.hbase.client.Put;</span>
<span class="source-line-no">117</span><span id="line-117">import org.apache.hadoop.hbase.client.RegionInfo;</span>
<span class="source-line-no">118</span><span id="line-118">import org.apache.hadoop.hbase.client.RegionInfoBuilder;</span>
<span class="source-line-no">119</span><span id="line-119">import org.apache.hadoop.hbase.client.Result;</span>
<span class="source-line-no">120</span><span id="line-120">import org.apache.hadoop.hbase.client.RowMutations;</span>
<span class="source-line-no">121</span><span id="line-121">import org.apache.hadoop.hbase.client.Scan;</span>
<span class="source-line-no">122</span><span id="line-122">import org.apache.hadoop.hbase.client.Table;</span>
<span class="source-line-no">123</span><span id="line-123">import org.apache.hadoop.hbase.client.TableDescriptor;</span>
<span class="source-line-no">124</span><span id="line-124">import org.apache.hadoop.hbase.client.TableDescriptorBuilder;</span>
<span class="source-line-no">125</span><span id="line-125">import org.apache.hadoop.hbase.coprocessor.CoprocessorHost;</span>
<span class="source-line-no">126</span><span id="line-126">import org.apache.hadoop.hbase.coprocessor.MetaTableMetrics;</span>
<span class="source-line-no">127</span><span id="line-127">import org.apache.hadoop.hbase.coprocessor.RegionCoprocessor;</span>
<span class="source-line-no">128</span><span id="line-128">import org.apache.hadoop.hbase.coprocessor.RegionObserver;</span>
<span class="source-line-no">129</span><span id="line-129">import org.apache.hadoop.hbase.exceptions.FailedSanityCheckException;</span>
<span class="source-line-no">130</span><span id="line-130">import org.apache.hadoop.hbase.filter.BigDecimalComparator;</span>
<span class="source-line-no">131</span><span id="line-131">import org.apache.hadoop.hbase.filter.BinaryComparator;</span>
<span class="source-line-no">132</span><span id="line-132">import org.apache.hadoop.hbase.filter.ColumnCountGetFilter;</span>
<span class="source-line-no">133</span><span id="line-133">import org.apache.hadoop.hbase.filter.Filter;</span>
<span class="source-line-no">134</span><span id="line-134">import org.apache.hadoop.hbase.filter.FilterBase;</span>
<span class="source-line-no">135</span><span id="line-135">import org.apache.hadoop.hbase.filter.FilterList;</span>
<span class="source-line-no">136</span><span id="line-136">import org.apache.hadoop.hbase.filter.NullComparator;</span>
<span class="source-line-no">137</span><span id="line-137">import org.apache.hadoop.hbase.filter.PrefixFilter;</span>
<span class="source-line-no">138</span><span id="line-138">import org.apache.hadoop.hbase.filter.SingleColumnValueExcludeFilter;</span>
<span class="source-line-no">139</span><span id="line-139">import org.apache.hadoop.hbase.filter.SingleColumnValueFilter;</span>
<span class="source-line-no">140</span><span id="line-140">import org.apache.hadoop.hbase.filter.SubstringComparator;</span>
<span class="source-line-no">141</span><span id="line-141">import org.apache.hadoop.hbase.filter.ValueFilter;</span>
<span class="source-line-no">142</span><span id="line-142">import org.apache.hadoop.hbase.io.TimeRange;</span>
<span class="source-line-no">143</span><span id="line-143">import org.apache.hadoop.hbase.io.hfile.HFile;</span>
<span class="source-line-no">144</span><span id="line-144">import org.apache.hadoop.hbase.monitoring.MonitoredRPCHandler;</span>
<span class="source-line-no">145</span><span id="line-145">import org.apache.hadoop.hbase.monitoring.MonitoredTask;</span>
<span class="source-line-no">146</span><span id="line-146">import org.apache.hadoop.hbase.monitoring.TaskMonitor;</span>
<span class="source-line-no">147</span><span id="line-147">import org.apache.hadoop.hbase.regionserver.Region.Operation;</span>
<span class="source-line-no">148</span><span id="line-148">import org.apache.hadoop.hbase.regionserver.Region.RowLock;</span>
<span class="source-line-no">149</span><span id="line-149">import org.apache.hadoop.hbase.regionserver.TestHStore.FaultyFileSystem;</span>
<span class="source-line-no">150</span><span id="line-150">import org.apache.hadoop.hbase.regionserver.compactions.CompactionRequestImpl;</span>
<span class="source-line-no">151</span><span id="line-151">import org.apache.hadoop.hbase.regionserver.wal.AbstractFSWAL;</span>
<span class="source-line-no">152</span><span id="line-152">import org.apache.hadoop.hbase.regionserver.wal.AsyncFSWAL;</span>
<span class="source-line-no">153</span><span id="line-153">import org.apache.hadoop.hbase.regionserver.wal.FSHLog;</span>
<span class="source-line-no">154</span><span id="line-154">import org.apache.hadoop.hbase.regionserver.wal.MetricsWALSource;</span>
<span class="source-line-no">155</span><span id="line-155">import org.apache.hadoop.hbase.regionserver.wal.WALUtil;</span>
<span class="source-line-no">156</span><span id="line-156">import org.apache.hadoop.hbase.replication.regionserver.ReplicationObserver;</span>
<span class="source-line-no">157</span><span id="line-157">import org.apache.hadoop.hbase.security.User;</span>
<span class="source-line-no">158</span><span id="line-158">import org.apache.hadoop.hbase.test.MetricsAssertHelper;</span>
<span class="source-line-no">159</span><span id="line-159">import org.apache.hadoop.hbase.testclassification.LargeTests;</span>
<span class="source-line-no">160</span><span id="line-160">import org.apache.hadoop.hbase.testclassification.VerySlowRegionServerTests;</span>
<span class="source-line-no">161</span><span id="line-161">import org.apache.hadoop.hbase.util.Bytes;</span>
<span class="source-line-no">162</span><span id="line-162">import org.apache.hadoop.hbase.util.CommonFSUtils;</span>
<span class="source-line-no">163</span><span id="line-163">import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;</span>
<span class="source-line-no">164</span><span id="line-164">import org.apache.hadoop.hbase.util.EnvironmentEdgeManagerTestHelper;</span>
<span class="source-line-no">165</span><span id="line-165">import org.apache.hadoop.hbase.util.HFileArchiveUtil;</span>
<span class="source-line-no">166</span><span id="line-166">import org.apache.hadoop.hbase.util.IncrementingEnvironmentEdge;</span>
<span class="source-line-no">167</span><span id="line-167">import org.apache.hadoop.hbase.util.ManualEnvironmentEdge;</span>
<span class="source-line-no">168</span><span id="line-168">import org.apache.hadoop.hbase.util.Threads;</span>
<span class="source-line-no">169</span><span id="line-169">import org.apache.hadoop.hbase.wal.AbstractFSWALProvider;</span>
<span class="source-line-no">170</span><span id="line-170">import org.apache.hadoop.hbase.wal.FaultyFSLog;</span>
<span class="source-line-no">171</span><span id="line-171">import org.apache.hadoop.hbase.wal.NettyAsyncFSWALConfigHelper;</span>
<span class="source-line-no">172</span><span id="line-172">import org.apache.hadoop.hbase.wal.WAL;</span>
<span class="source-line-no">173</span><span id="line-173">import org.apache.hadoop.hbase.wal.WALEdit;</span>
<span class="source-line-no">174</span><span id="line-174">import org.apache.hadoop.hbase.wal.WALFactory;</span>
<span class="source-line-no">175</span><span id="line-175">import org.apache.hadoop.hbase.wal.WALKeyImpl;</span>
<span class="source-line-no">176</span><span id="line-176">import org.apache.hadoop.hbase.wal.WALProvider;</span>
<span class="source-line-no">177</span><span id="line-177">import org.apache.hadoop.hbase.wal.WALProvider.Writer;</span>
<span class="source-line-no">178</span><span id="line-178">import org.apache.hadoop.hbase.wal.WALSplitUtil;</span>
<span class="source-line-no">179</span><span id="line-179">import org.apache.hadoop.hbase.wal.WALStreamReader;</span>
<span class="source-line-no">180</span><span id="line-180">import org.junit.After;</span>
<span class="source-line-no">181</span><span id="line-181">import org.junit.Assert;</span>
<span class="source-line-no">182</span><span id="line-182">import org.junit.Before;</span>
<span class="source-line-no">183</span><span id="line-183">import org.junit.ClassRule;</span>
<span class="source-line-no">184</span><span id="line-184">import org.junit.Ignore;</span>
<span class="source-line-no">185</span><span id="line-185">import org.junit.Rule;</span>
<span class="source-line-no">186</span><span id="line-186">import org.junit.Test;</span>
<span class="source-line-no">187</span><span id="line-187">import org.junit.experimental.categories.Category;</span>
<span class="source-line-no">188</span><span id="line-188">import org.junit.rules.ExpectedException;</span>
<span class="source-line-no">189</span><span id="line-189">import org.junit.rules.TestName;</span>
<span class="source-line-no">190</span><span id="line-190">import org.mockito.ArgumentCaptor;</span>
<span class="source-line-no">191</span><span id="line-191">import org.mockito.ArgumentMatcher;</span>
<span class="source-line-no">192</span><span id="line-192">import org.mockito.invocation.InvocationOnMock;</span>
<span class="source-line-no">193</span><span id="line-193">import org.mockito.stubbing.Answer;</span>
<span class="source-line-no">194</span><span id="line-194">import org.slf4j.Logger;</span>
<span class="source-line-no">195</span><span id="line-195">import org.slf4j.LoggerFactory;</span>
<span class="source-line-no">196</span><span id="line-196"></span>
<span class="source-line-no">197</span><span id="line-197">import org.apache.hbase.thirdparty.com.google.common.collect.Lists;</span>
<span class="source-line-no">198</span><span id="line-198">import org.apache.hbase.thirdparty.com.google.protobuf.ByteString;</span>
<span class="source-line-no">199</span><span id="line-199">import org.apache.hbase.thirdparty.io.netty.channel.EventLoopGroup;</span>
<span class="source-line-no">200</span><span id="line-200">import org.apache.hbase.thirdparty.io.netty.channel.nio.NioEventLoopGroup;</span>
<span class="source-line-no">201</span><span id="line-201">import org.apache.hbase.thirdparty.io.netty.channel.socket.nio.NioSocketChannel;</span>
<span class="source-line-no">202</span><span id="line-202"></span>
<span class="source-line-no">203</span><span id="line-203">import org.apache.hadoop.hbase.shaded.protobuf.ProtobufUtil;</span>
<span class="source-line-no">204</span><span id="line-204">import org.apache.hadoop.hbase.shaded.protobuf.generated.WALProtos.CompactionDescriptor;</span>
<span class="source-line-no">205</span><span id="line-205">import org.apache.hadoop.hbase.shaded.protobuf.generated.WALProtos.FlushDescriptor;</span>
<span class="source-line-no">206</span><span id="line-206">import org.apache.hadoop.hbase.shaded.protobuf.generated.WALProtos.FlushDescriptor.FlushAction;</span>
<span class="source-line-no">207</span><span id="line-207">import org.apache.hadoop.hbase.shaded.protobuf.generated.WALProtos.FlushDescriptor.StoreFlushDescriptor;</span>
<span class="source-line-no">208</span><span id="line-208">import org.apache.hadoop.hbase.shaded.protobuf.generated.WALProtos.RegionEventDescriptor;</span>
<span class="source-line-no">209</span><span id="line-209">import org.apache.hadoop.hbase.shaded.protobuf.generated.WALProtos.StoreDescriptor;</span>
<span class="source-line-no">210</span><span id="line-210"></span>
<span class="source-line-no">211</span><span id="line-211">/**</span>
<span class="source-line-no">212</span><span id="line-212"> * Basic stand-alone testing of HRegion. No clusters! A lot of the meta information for an HRegion</span>
<span class="source-line-no">213</span><span id="line-213"> * now lives inside other HRegions or in the HBaseMaster, so only basic testing is possible.</span>
<span class="source-line-no">214</span><span id="line-214"> */</span>
<span class="source-line-no">215</span><span id="line-215">@Category({ VerySlowRegionServerTests.class, LargeTests.class })</span>
<span class="source-line-no">216</span><span id="line-216">@SuppressWarnings("deprecation")</span>
<span class="source-line-no">217</span><span id="line-217">public class TestHRegion {</span>
<span class="source-line-no">218</span><span id="line-218"></span>
<span class="source-line-no">219</span><span id="line-219"> @ClassRule</span>
<span class="source-line-no">220</span><span id="line-220"> public static final HBaseClassTestRule CLASS_RULE =</span>
<span class="source-line-no">221</span><span id="line-221"> HBaseClassTestRule.forClass(TestHRegion.class);</span>
<span class="source-line-no">222</span><span id="line-222"></span>
<span class="source-line-no">223</span><span id="line-223"> // Do not spin up clusters in here. If you need to spin up a cluster, do it</span>
<span class="source-line-no">224</span><span id="line-224"> // over in TestHRegionOnCluster.</span>
<span class="source-line-no">225</span><span id="line-225"> private static final Logger LOG = LoggerFactory.getLogger(TestHRegion.class);</span>
<span class="source-line-no">226</span><span id="line-226"> @Rule</span>
<span class="source-line-no">227</span><span id="line-227"> public TestName name = new TestName();</span>
<span class="source-line-no">228</span><span id="line-228"> @Rule</span>
<span class="source-line-no">229</span><span id="line-229"> public final ExpectedException thrown = ExpectedException.none();</span>
<span class="source-line-no">230</span><span id="line-230"></span>
<span class="source-line-no">231</span><span id="line-231"> private static final String COLUMN_FAMILY = "MyCF";</span>
<span class="source-line-no">232</span><span id="line-232"> private static final byte[] COLUMN_FAMILY_BYTES = Bytes.toBytes(COLUMN_FAMILY);</span>
<span class="source-line-no">233</span><span id="line-233"> private static final EventLoopGroup GROUP = new NioEventLoopGroup();</span>
<span class="source-line-no">234</span><span id="line-234"></span>
<span class="source-line-no">235</span><span id="line-235"> HRegion region = null;</span>
<span class="source-line-no">236</span><span id="line-236"> // Do not run unit tests in parallel (? Why not? It don't work? Why not? St.Ack)</span>
<span class="source-line-no">237</span><span id="line-237"> protected static HBaseTestingUtil TEST_UTIL;</span>
<span class="source-line-no">238</span><span id="line-238"> public static Configuration CONF;</span>
<span class="source-line-no">239</span><span id="line-239"> private String dir;</span>
<span class="source-line-no">240</span><span id="line-240"> private final int MAX_VERSIONS = 2;</span>
<span class="source-line-no">241</span><span id="line-241"></span>
<span class="source-line-no">242</span><span id="line-242"> // Test names</span>
<span class="source-line-no">243</span><span id="line-243"> protected TableName tableName;</span>
<span class="source-line-no">244</span><span id="line-244"> protected String method;</span>
<span class="source-line-no">245</span><span id="line-245"> protected final byte[] qual = Bytes.toBytes("qual");</span>
<span class="source-line-no">246</span><span id="line-246"> protected final byte[] qual1 = Bytes.toBytes("qual1");</span>
<span class="source-line-no">247</span><span id="line-247"> protected final byte[] qual2 = Bytes.toBytes("qual2");</span>
<span class="source-line-no">248</span><span id="line-248"> protected final byte[] qual3 = Bytes.toBytes("qual3");</span>
<span class="source-line-no">249</span><span id="line-249"> protected final byte[] value = Bytes.toBytes("value");</span>
<span class="source-line-no">250</span><span id="line-250"> protected final byte[] value1 = Bytes.toBytes("value1");</span>
<span class="source-line-no">251</span><span id="line-251"> protected final byte[] value2 = Bytes.toBytes("value2");</span>
<span class="source-line-no">252</span><span id="line-252"> protected final byte[] row = Bytes.toBytes("rowA");</span>
<span class="source-line-no">253</span><span id="line-253"> protected final byte[] row2 = Bytes.toBytes("rowB");</span>
<span class="source-line-no">254</span><span id="line-254"></span>
<span class="source-line-no">255</span><span id="line-255"> protected final MetricsAssertHelper metricsAssertHelper =</span>
<span class="source-line-no">256</span><span id="line-256"> CompatibilitySingletonFactory.getInstance(MetricsAssertHelper.class);</span>
<span class="source-line-no">257</span><span id="line-257"></span>
<span class="source-line-no">258</span><span id="line-258"> @Before</span>
<span class="source-line-no">259</span><span id="line-259"> public void setup() throws IOException {</span>
<span class="source-line-no">260</span><span id="line-260"> TEST_UTIL = new HBaseTestingUtil();</span>
<span class="source-line-no">261</span><span id="line-261"> CONF = TEST_UTIL.getConfiguration();</span>
<span class="source-line-no">262</span><span id="line-262"> NettyAsyncFSWALConfigHelper.setEventLoopConfig(CONF, GROUP, NioSocketChannel.class);</span>
<span class="source-line-no">263</span><span id="line-263"> dir = TEST_UTIL.getDataTestDir("TestHRegion").toString();</span>
<span class="source-line-no">264</span><span id="line-264"> method = name.getMethodName();</span>
<span class="source-line-no">265</span><span id="line-265"> tableName = TableName.valueOf(method);</span>
<span class="source-line-no">266</span><span id="line-266"> CONF.set(CompactingMemStore.IN_MEMORY_FLUSH_THRESHOLD_FACTOR_KEY, String.valueOf(0.09));</span>
<span class="source-line-no">267</span><span id="line-267"> CONF.setLong(AbstractFSWAL.WAL_SYNC_TIMEOUT_MS, 10000);</span>
<span class="source-line-no">268</span><span id="line-268"> }</span>
<span class="source-line-no">269</span><span id="line-269"></span>
<span class="source-line-no">270</span><span id="line-270"> @After</span>
<span class="source-line-no">271</span><span id="line-271"> public void tearDown() throws IOException {</span>
<span class="source-line-no">272</span><span id="line-272"> // Region may have been closed, but it is still no harm if we close it again here using HTU.</span>
<span class="source-line-no">273</span><span id="line-273"> HBaseTestingUtil.closeRegionAndWAL(region);</span>
<span class="source-line-no">274</span><span id="line-274"> EnvironmentEdgeManagerTestHelper.reset();</span>
<span class="source-line-no">275</span><span id="line-275"> LOG.info("Cleaning test directory: " + TEST_UTIL.getDataTestDir());</span>
<span class="source-line-no">276</span><span id="line-276"> TEST_UTIL.cleanupTestDir();</span>
<span class="source-line-no">277</span><span id="line-277"> }</span>
<span class="source-line-no">278</span><span id="line-278"></span>
<span class="source-line-no">279</span><span id="line-279"> /**</span>
<span class="source-line-no">280</span><span id="line-280"> * Test that I can use the max flushed sequence id after the close.</span>
<span class="source-line-no">281</span><span id="line-281"> */</span>
<span class="source-line-no">282</span><span id="line-282"> @Test</span>
<span class="source-line-no">283</span><span id="line-283"> public void testSequenceId() throws IOException {</span>
<span class="source-line-no">284</span><span id="line-284"> region = initHRegion(tableName, method, CONF, COLUMN_FAMILY_BYTES);</span>
<span class="source-line-no">285</span><span id="line-285"> assertEquals(HConstants.NO_SEQNUM, region.getMaxFlushedSeqId());</span>
<span class="source-line-no">286</span><span id="line-286"> // Weird. This returns 0 if no store files or no edits. Afraid to change it.</span>
<span class="source-line-no">287</span><span id="line-287"> assertEquals(0, (long) region.getMaxStoreSeqId().get(COLUMN_FAMILY_BYTES));</span>
<span class="source-line-no">288</span><span id="line-288"> HBaseTestingUtil.closeRegionAndWAL(this.region);</span>
<span class="source-line-no">289</span><span id="line-289"> assertEquals(HConstants.NO_SEQNUM, region.getMaxFlushedSeqId());</span>
<span class="source-line-no">290</span><span id="line-290"> assertEquals(0, (long) region.getMaxStoreSeqId().get(COLUMN_FAMILY_BYTES));</span>
<span class="source-line-no">291</span><span id="line-291"> HRegion oldRegion = region;</span>
<span class="source-line-no">292</span><span id="line-292"> try {</span>
<span class="source-line-no">293</span><span id="line-293"> // Open region again.</span>
<span class="source-line-no">294</span><span id="line-294"> region = initHRegion(tableName, method, CONF, COLUMN_FAMILY_BYTES);</span>
<span class="source-line-no">295</span><span id="line-295"> byte[] value = Bytes.toBytes(method);</span>
<span class="source-line-no">296</span><span id="line-296"> // Make a random put against our cf.</span>
<span class="source-line-no">297</span><span id="line-297"> Put put = new Put(value);</span>
<span class="source-line-no">298</span><span id="line-298"> put.addColumn(COLUMN_FAMILY_BYTES, null, value);</span>
<span class="source-line-no">299</span><span id="line-299"> region.put(put);</span>
<span class="source-line-no">300</span><span id="line-300"> // No flush yet so init numbers should still be in place.</span>
<span class="source-line-no">301</span><span id="line-301"> assertEquals(HConstants.NO_SEQNUM, region.getMaxFlushedSeqId());</span>
<span class="source-line-no">302</span><span id="line-302"> assertEquals(0, (long) region.getMaxStoreSeqId().get(COLUMN_FAMILY_BYTES));</span>
<span class="source-line-no">303</span><span id="line-303"> region.flush(true);</span>
<span class="source-line-no">304</span><span id="line-304"> long max = region.getMaxFlushedSeqId();</span>
<span class="source-line-no">305</span><span id="line-305"> HBaseTestingUtil.closeRegionAndWAL(this.region);</span>
<span class="source-line-no">306</span><span id="line-306"> assertEquals(max, region.getMaxFlushedSeqId());</span>
<span class="source-line-no">307</span><span id="line-307"> this.region = null;</span>
<span class="source-line-no">308</span><span id="line-308"> } finally {</span>
<span class="source-line-no">309</span><span id="line-309"> HBaseTestingUtil.closeRegionAndWAL(oldRegion);</span>
<span class="source-line-no">310</span><span id="line-310"> }</span>
<span class="source-line-no">311</span><span id="line-311"> }</span>
<span class="source-line-no">312</span><span id="line-312"></span>
<span class="source-line-no">313</span><span id="line-313"> /**</span>
<span class="source-line-no">314</span><span id="line-314"> * Test for Bug 2 of HBASE-10466. "Bug 2: Conditions for the first flush of region close</span>
<span class="source-line-no">315</span><span id="line-315"> * (so-called pre-flush) If memstoreSize is smaller than a certain value, or when region close</span>
<span class="source-line-no">316</span><span id="line-316"> * starts a flush is ongoing, the first flush is skipped and only the second flush takes place.</span>
<span class="source-line-no">317</span><span id="line-317"> * However, two flushes are required in case previous flush fails and leaves some data in</span>
<span class="source-line-no">318</span><span id="line-318"> * snapshot. The bug could cause loss of data in current memstore. The fix is removing all</span>
<span class="source-line-no">319</span><span id="line-319"> * conditions except abort check so we ensure 2 flushes for region close."</span>
<span class="source-line-no">320</span><span id="line-320"> */</span>
<span class="source-line-no">321</span><span id="line-321"> @Test</span>
<span class="source-line-no">322</span><span id="line-322"> public void testCloseCarryingSnapshot() throws IOException {</span>
<span class="source-line-no">323</span><span id="line-323"> region = initHRegion(tableName, method, CONF, COLUMN_FAMILY_BYTES);</span>
<span class="source-line-no">324</span><span id="line-324"> HStore store = region.getStore(COLUMN_FAMILY_BYTES);</span>
<span class="source-line-no">325</span><span id="line-325"> // Get some random bytes.</span>
<span class="source-line-no">326</span><span id="line-326"> byte[] value = Bytes.toBytes(method);</span>
<span class="source-line-no">327</span><span id="line-327"> // Make a random put against our cf.</span>
<span class="source-line-no">328</span><span id="line-328"> Put put = new Put(value);</span>
<span class="source-line-no">329</span><span id="line-329"> put.addColumn(COLUMN_FAMILY_BYTES, null, value);</span>
<span class="source-line-no">330</span><span id="line-330"> // First put something in current memstore, which will be in snapshot after flusher.prepare()</span>
<span class="source-line-no">331</span><span id="line-331"> region.put(put);</span>
<span class="source-line-no">332</span><span id="line-332"> StoreFlushContext storeFlushCtx = store.createFlushContext(12345, FlushLifeCycleTracker.DUMMY);</span>
<span class="source-line-no">333</span><span id="line-333"> storeFlushCtx.prepare();</span>
<span class="source-line-no">334</span><span id="line-334"> // Second put something in current memstore</span>
<span class="source-line-no">335</span><span id="line-335"> put.addColumn(COLUMN_FAMILY_BYTES, Bytes.toBytes("abc"), value);</span>
<span class="source-line-no">336</span><span id="line-336"> region.put(put);</span>
<span class="source-line-no">337</span><span id="line-337"> // Close with something in memstore and something in the snapshot. Make sure all is cleared.</span>
<span class="source-line-no">338</span><span id="line-338"> HBaseTestingUtil.closeRegionAndWAL(region);</span>
<span class="source-line-no">339</span><span id="line-339"> assertEquals(0, region.getMemStoreDataSize());</span>
<span class="source-line-no">340</span><span id="line-340"> region = null;</span>
<span class="source-line-no">341</span><span id="line-341"> }</span>
<span class="source-line-no">342</span><span id="line-342"></span>
<span class="source-line-no">343</span><span id="line-343"> /*</span>
<span class="source-line-no">344</span><span id="line-344"> * This test is for verifying memstore snapshot size is correctly updated in case of rollback See</span>
<span class="source-line-no">345</span><span id="line-345"> * HBASE-10845</span>
<span class="source-line-no">346</span><span id="line-346"> */</span>
<span class="source-line-no">347</span><span id="line-347"> @Test</span>
<span class="source-line-no">348</span><span id="line-348"> public void testMemstoreSnapshotSize() throws IOException {</span>
<span class="source-line-no">349</span><span id="line-349"> class MyFaultyFSLog extends FaultyFSLog {</span>
<span class="source-line-no">350</span><span id="line-350"> StoreFlushContext storeFlushCtx;</span>
<span class="source-line-no">351</span><span id="line-351"></span>
<span class="source-line-no">352</span><span id="line-352"> public MyFaultyFSLog(FileSystem fs, Path rootDir, String logName, Configuration conf)</span>
<span class="source-line-no">353</span><span id="line-353"> throws IOException {</span>
<span class="source-line-no">354</span><span id="line-354"> super(fs, rootDir, logName, conf);</span>
<span class="source-line-no">355</span><span id="line-355"> }</span>
<span class="source-line-no">356</span><span id="line-356"></span>
<span class="source-line-no">357</span><span id="line-357"> void setStoreFlushCtx(StoreFlushContext storeFlushCtx) {</span>
<span class="source-line-no">358</span><span id="line-358"> this.storeFlushCtx = storeFlushCtx;</span>
<span class="source-line-no">359</span><span id="line-359"> }</span>
<span class="source-line-no">360</span><span id="line-360"></span>
<span class="source-line-no">361</span><span id="line-361"> @Override</span>
<span class="source-line-no">362</span><span id="line-362"> protected void doSync(long txid, boolean forceSync) throws IOException {</span>
<span class="source-line-no">363</span><span id="line-363"> storeFlushCtx.prepare();</span>
<span class="source-line-no">364</span><span id="line-364"> super.doSync(txid, forceSync);</span>
<span class="source-line-no">365</span><span id="line-365"> }</span>
<span class="source-line-no">366</span><span id="line-366"> }</span>
<span class="source-line-no">367</span><span id="line-367"></span>
<span class="source-line-no">368</span><span id="line-368"> FileSystem fs = FileSystem.get(CONF);</span>
<span class="source-line-no">369</span><span id="line-369"> Path rootDir = new Path(dir + "testMemstoreSnapshotSize");</span>
<span class="source-line-no">370</span><span id="line-370"> MyFaultyFSLog faultyLog = new MyFaultyFSLog(fs, rootDir, "testMemstoreSnapshotSize", CONF);</span>
<span class="source-line-no">371</span><span id="line-371"> faultyLog.init();</span>
<span class="source-line-no">372</span><span id="line-372"> region = initHRegion(tableName, null, null, CONF, false, Durability.SYNC_WAL, faultyLog,</span>
<span class="source-line-no">373</span><span id="line-373"> COLUMN_FAMILY_BYTES);</span>
<span class="source-line-no">374</span><span id="line-374"></span>
<span class="source-line-no">375</span><span id="line-375"> HStore store = region.getStore(COLUMN_FAMILY_BYTES);</span>
<span class="source-line-no">376</span><span id="line-376"> // Get some random bytes.</span>
<span class="source-line-no">377</span><span id="line-377"> byte[] value = Bytes.toBytes(method);</span>
<span class="source-line-no">378</span><span id="line-378"> faultyLog.setStoreFlushCtx(store.createFlushContext(12345, FlushLifeCycleTracker.DUMMY));</span>
<span class="source-line-no">379</span><span id="line-379"></span>
<span class="source-line-no">380</span><span id="line-380"> Put put = new Put(value);</span>
<span class="source-line-no">381</span><span id="line-381"> put.addColumn(COLUMN_FAMILY_BYTES, Bytes.toBytes("abc"), value);</span>
<span class="source-line-no">382</span><span id="line-382"> faultyLog.setFailureType(FaultyFSLog.FailureType.SYNC);</span>
<span class="source-line-no">383</span><span id="line-383"> boolean threwIOE = false;</span>
<span class="source-line-no">384</span><span id="line-384"> try {</span>
<span class="source-line-no">385</span><span id="line-385"> region.put(put);</span>
<span class="source-line-no">386</span><span id="line-386"> } catch (IOException ioe) {</span>
<span class="source-line-no">387</span><span id="line-387"> threwIOE = true;</span>
<span class="source-line-no">388</span><span id="line-388"> } finally {</span>
<span class="source-line-no">389</span><span id="line-389"> assertTrue("The regionserver should have thrown an exception", threwIOE);</span>
<span class="source-line-no">390</span><span id="line-390"> }</span>
<span class="source-line-no">391</span><span id="line-391"> MemStoreSize mss = store.getFlushableSize();</span>
<span class="source-line-no">392</span><span id="line-392"> assertTrue("flushable size should be zero, but it is " + mss, mss.getDataSize() == 0);</span>
<span class="source-line-no">393</span><span id="line-393"> }</span>
<span class="source-line-no">394</span><span id="line-394"></span>
<span class="source-line-no">395</span><span id="line-395"> /**</span>
<span class="source-line-no">396</span><span id="line-396"> * Create a WAL outside of the usual helper in</span>
<span class="source-line-no">397</span><span id="line-397"> * {@link HBaseTestingUtil#createWal(Configuration, Path, RegionInfo)} because that method doesn't</span>
<span class="source-line-no">398</span><span id="line-398"> * play nicely with FaultyFileSystem. Call this method before overriding {@code fs.file.impl}.</span>
<span class="source-line-no">399</span><span id="line-399"> * @param callingMethod a unique component for the path, probably the name of the test method.</span>
<span class="source-line-no">400</span><span id="line-400"> */</span>
<span class="source-line-no">401</span><span id="line-401"> private static WAL createWALCompatibleWithFaultyFileSystem(String callingMethod,</span>
<span class="source-line-no">402</span><span id="line-402"> Configuration conf, TableName tableName) throws IOException {</span>
<span class="source-line-no">403</span><span id="line-403"> final Path logDir = TEST_UTIL.getDataTestDirOnTestFS(callingMethod + ".log");</span>
<span class="source-line-no">404</span><span id="line-404"> final Configuration walConf = new Configuration(conf);</span>
<span class="source-line-no">405</span><span id="line-405"> CommonFSUtils.setRootDir(walConf, logDir);</span>
<span class="source-line-no">406</span><span id="line-406"> return new WALFactory(walConf, callingMethod)</span>
<span class="source-line-no">407</span><span id="line-407"> .getWAL(RegionInfoBuilder.newBuilder(tableName).build());</span>
<span class="source-line-no">408</span><span id="line-408"> }</span>
<span class="source-line-no">409</span><span id="line-409"></span>
<span class="source-line-no">410</span><span id="line-410"> @Test</span>
<span class="source-line-no">411</span><span id="line-411"> public void testMemstoreSizeAccountingWithFailedPostBatchMutate() throws IOException {</span>
<span class="source-line-no">412</span><span id="line-412"> String testName = "testMemstoreSizeAccountingWithFailedPostBatchMutate";</span>
<span class="source-line-no">413</span><span id="line-413"> FileSystem fs = FileSystem.get(CONF);</span>
<span class="source-line-no">414</span><span id="line-414"> Path rootDir = new Path(dir + testName);</span>
<span class="source-line-no">415</span><span id="line-415"> FSHLog hLog = new FSHLog(fs, rootDir, testName, CONF);</span>
<span class="source-line-no">416</span><span id="line-416"> hLog.init();</span>
<span class="source-line-no">417</span><span id="line-417"> region = initHRegion(tableName, null, null, CONF, false, Durability.SYNC_WAL, hLog,</span>
<span class="source-line-no">418</span><span id="line-418"> COLUMN_FAMILY_BYTES);</span>
<span class="source-line-no">419</span><span id="line-419"> HStore store = region.getStore(COLUMN_FAMILY_BYTES);</span>
<span class="source-line-no">420</span><span id="line-420"> assertEquals(0, region.getMemStoreDataSize());</span>
<span class="source-line-no">421</span><span id="line-421"></span>
<span class="source-line-no">422</span><span id="line-422"> // Put one value</span>
<span class="source-line-no">423</span><span id="line-423"> byte[] value = Bytes.toBytes(method);</span>
<span class="source-line-no">424</span><span id="line-424"> Put put = new Put(value);</span>
<span class="source-line-no">425</span><span id="line-425"> put.addColumn(COLUMN_FAMILY_BYTES, Bytes.toBytes("abc"), value);</span>
<span class="source-line-no">426</span><span id="line-426"> region.put(put);</span>
<span class="source-line-no">427</span><span id="line-427"> long onePutSize = region.getMemStoreDataSize();</span>
<span class="source-line-no">428</span><span id="line-428"> assertTrue(onePutSize &gt; 0);</span>
<span class="source-line-no">429</span><span id="line-429"></span>
<span class="source-line-no">430</span><span id="line-430"> RegionCoprocessorHost mockedCPHost = mock(RegionCoprocessorHost.class);</span>
<span class="source-line-no">431</span><span id="line-431"> doThrow(new IOException()).when(mockedCPHost).postBatchMutate(any());</span>
<span class="source-line-no">432</span><span id="line-432"> region.setCoprocessorHost(mockedCPHost);</span>
<span class="source-line-no">433</span><span id="line-433"></span>
<span class="source-line-no">434</span><span id="line-434"> put = new Put(value);</span>
<span class="source-line-no">435</span><span id="line-435"> put.addColumn(COLUMN_FAMILY_BYTES, Bytes.toBytes("dfg"), value);</span>
<span class="source-line-no">436</span><span id="line-436"> try {</span>
<span class="source-line-no">437</span><span id="line-437"> region.put(put);</span>
<span class="source-line-no">438</span><span id="line-438"> fail("Should have failed with IOException");</span>
<span class="source-line-no">439</span><span id="line-439"> } catch (IOException expected) {</span>
<span class="source-line-no">440</span><span id="line-440"> }</span>
<span class="source-line-no">441</span><span id="line-441"> long expectedSize = onePutSize * 2;</span>
<span class="source-line-no">442</span><span id="line-442"> assertEquals("memstoreSize should be incremented", expectedSize, region.getMemStoreDataSize());</span>
<span class="source-line-no">443</span><span id="line-443"> assertEquals("flushable size should be incremented", expectedSize,</span>
<span class="source-line-no">444</span><span id="line-444"> store.getFlushableSize().getDataSize());</span>
<span class="source-line-no">445</span><span id="line-445"></span>
<span class="source-line-no">446</span><span id="line-446"> region.setCoprocessorHost(null);</span>
<span class="source-line-no">447</span><span id="line-447"> }</span>
<span class="source-line-no">448</span><span id="line-448"></span>
<span class="source-line-no">449</span><span id="line-449"> /**</span>
<span class="source-line-no">450</span><span id="line-450"> * A test case of HBASE-21041</span>
<span class="source-line-no">451</span><span id="line-451"> */</span>
<span class="source-line-no">452</span><span id="line-452"> @Test</span>
<span class="source-line-no">453</span><span id="line-453"> public void testFlushAndMemstoreSizeCounting() throws Exception {</span>
<span class="source-line-no">454</span><span id="line-454"> byte[] family = Bytes.toBytes("family");</span>
<span class="source-line-no">455</span><span id="line-455"> this.region = initHRegion(tableName, method, CONF, family);</span>
<span class="source-line-no">456</span><span id="line-456"> for (byte[] row : HBaseTestingUtil.ROWS) {</span>
<span class="source-line-no">457</span><span id="line-457"> Put put = new Put(row);</span>
<span class="source-line-no">458</span><span id="line-458"> put.addColumn(family, family, row);</span>
<span class="source-line-no">459</span><span id="line-459"> region.put(put);</span>
<span class="source-line-no">460</span><span id="line-460"> }</span>
<span class="source-line-no">461</span><span id="line-461"> region.flush(true);</span>
<span class="source-line-no">462</span><span id="line-462"> // After flush, data size should be zero</span>
<span class="source-line-no">463</span><span id="line-463"> assertEquals(0, region.getMemStoreDataSize());</span>
<span class="source-line-no">464</span><span id="line-464"> // After flush, a new active mutable segment is created, so the heap size</span>
<span class="source-line-no">465</span><span id="line-465"> // should equal to MutableSegment.DEEP_OVERHEAD</span>
<span class="source-line-no">466</span><span id="line-466"> assertEquals(MutableSegment.DEEP_OVERHEAD, region.getMemStoreHeapSize());</span>
<span class="source-line-no">467</span><span id="line-467"> // After flush, offheap should be zero</span>
<span class="source-line-no">468</span><span id="line-468"> assertEquals(0, region.getMemStoreOffHeapSize());</span>
<span class="source-line-no">469</span><span id="line-469"> }</span>
<span class="source-line-no">470</span><span id="line-470"></span>
<span class="source-line-no">471</span><span id="line-471"> /**</span>
<span class="source-line-no">472</span><span id="line-472"> * Test we do not lose data if we fail a flush and then close. Part of HBase-10466. Tests the</span>
<span class="source-line-no">473</span><span id="line-473"> * following from the issue description: "Bug 1: Wrong calculation of HRegion.memstoreSize: When a</span>
<span class="source-line-no">474</span><span id="line-474"> * flush fails, data to be flushed is kept in each MemStore's snapshot and wait for next flush</span>
<span class="source-line-no">475</span><span id="line-475"> * attempt to continue on it. But when the next flush succeeds, the counter of total memstore size</span>
<span class="source-line-no">476</span><span id="line-476"> * in HRegion is always deduced by the sum of current memstore sizes instead of snapshots left</span>
<span class="source-line-no">477</span><span id="line-477"> * from previous failed flush. This calculation is problematic that almost every time there is</span>
<span class="source-line-no">478</span><span id="line-478"> * failed flush, HRegion.memstoreSize gets reduced by a wrong value. If region flush could not</span>
<span class="source-line-no">479</span><span id="line-479"> * proceed for a couple cycles, the size in current memstore could be much larger than the</span>
<span class="source-line-no">480</span><span id="line-480"> * snapshot. It's likely to drift memstoreSize much smaller than expected. In extreme case, if the</span>
<span class="source-line-no">481</span><span id="line-481"> * error accumulates to even bigger than HRegion's memstore size limit, any further flush is</span>
<span class="source-line-no">482</span><span id="line-482"> * skipped because flush does not do anything if memstoreSize is not larger than 0."</span>
<span class="source-line-no">483</span><span id="line-483"> */</span>
<span class="source-line-no">484</span><span id="line-484"> @Test</span>
<span class="source-line-no">485</span><span id="line-485"> public void testFlushSizeAccounting() throws Exception {</span>
<span class="source-line-no">486</span><span id="line-486"> final Configuration conf = HBaseConfiguration.create(CONF);</span>
<span class="source-line-no">487</span><span id="line-487"> final WAL wal = createWALCompatibleWithFaultyFileSystem(method, conf, tableName);</span>
<span class="source-line-no">488</span><span id="line-488"> // Only retry once.</span>
<span class="source-line-no">489</span><span id="line-489"> conf.setInt("hbase.hstore.flush.retries.number", 1);</span>
<span class="source-line-no">490</span><span id="line-490"> final User user = User.createUserForTesting(conf, method, new String[] { "foo" });</span>
<span class="source-line-no">491</span><span id="line-491"> // Inject our faulty LocalFileSystem</span>
<span class="source-line-no">492</span><span id="line-492"> conf.setClass("fs.file.impl", FaultyFileSystem.class, FileSystem.class);</span>
<span class="source-line-no">493</span><span id="line-493"> user.runAs(new PrivilegedExceptionAction&lt;Object&gt;() {</span>
<span class="source-line-no">494</span><span id="line-494"> @Override</span>
<span class="source-line-no">495</span><span id="line-495"> public Object run() throws Exception {</span>
<span class="source-line-no">496</span><span id="line-496"> // Make sure it worked (above is sensitive to caching details in hadoop core)</span>
<span class="source-line-no">497</span><span id="line-497"> FileSystem fs = FileSystem.get(conf);</span>
<span class="source-line-no">498</span><span id="line-498"> Assert.assertEquals(FaultyFileSystem.class, fs.getClass());</span>
<span class="source-line-no">499</span><span id="line-499"> FaultyFileSystem ffs = (FaultyFileSystem) fs;</span>
<span class="source-line-no">500</span><span id="line-500"> HRegion region = null;</span>
<span class="source-line-no">501</span><span id="line-501"> try {</span>
<span class="source-line-no">502</span><span id="line-502"> // Initialize region</span>
<span class="source-line-no">503</span><span id="line-503"> region = initHRegion(tableName, null, null, CONF, false, Durability.SYNC_WAL, wal,</span>
<span class="source-line-no">504</span><span id="line-504"> COLUMN_FAMILY_BYTES);</span>
<span class="source-line-no">505</span><span id="line-505"> long size = region.getMemStoreDataSize();</span>
<span class="source-line-no">506</span><span id="line-506"> Assert.assertEquals(0, size);</span>
<span class="source-line-no">507</span><span id="line-507"> // Put one item into memstore. Measure the size of one item in memstore.</span>
<span class="source-line-no">508</span><span id="line-508"> Put p1 = new Put(row);</span>
<span class="source-line-no">509</span><span id="line-509"> p1.add(new KeyValue(row, COLUMN_FAMILY_BYTES, qual1, 1, (byte[]) null));</span>
<span class="source-line-no">510</span><span id="line-510"> region.put(p1);</span>
<span class="source-line-no">511</span><span id="line-511"> final long sizeOfOnePut = region.getMemStoreDataSize();</span>
<span class="source-line-no">512</span><span id="line-512"> // Fail a flush which means the current memstore will hang out as memstore 'snapshot'.</span>
<span class="source-line-no">513</span><span id="line-513"> try {</span>
<span class="source-line-no">514</span><span id="line-514"> LOG.info("Flushing");</span>
<span class="source-line-no">515</span><span id="line-515"> region.flush(true);</span>
<span class="source-line-no">516</span><span id="line-516"> Assert.fail("Didn't bubble up IOE!");</span>
<span class="source-line-no">517</span><span id="line-517"> } catch (DroppedSnapshotException dse) {</span>
<span class="source-line-no">518</span><span id="line-518"> // What we are expecting</span>
<span class="source-line-no">519</span><span id="line-519"> region.closing.set(false); // this is needed for the rest of the test to work</span>
<span class="source-line-no">520</span><span id="line-520"> }</span>
<span class="source-line-no">521</span><span id="line-521"> // Make it so all writes succeed from here on out</span>
<span class="source-line-no">522</span><span id="line-522"> ffs.fault.set(false);</span>
<span class="source-line-no">523</span><span id="line-523"> // Check sizes. Should still be the one entry.</span>
<span class="source-line-no">524</span><span id="line-524"> Assert.assertEquals(sizeOfOnePut, region.getMemStoreDataSize());</span>
<span class="source-line-no">525</span><span id="line-525"> // Now add two entries so that on this next flush that fails, we can see if we</span>
<span class="source-line-no">526</span><span id="line-526"> // subtract the right amount, the snapshot size only.</span>
<span class="source-line-no">527</span><span id="line-527"> Put p2 = new Put(row);</span>
<span class="source-line-no">528</span><span id="line-528"> p2.add(new KeyValue(row, COLUMN_FAMILY_BYTES, qual2, 2, (byte[]) null));</span>
<span class="source-line-no">529</span><span id="line-529"> p2.add(new KeyValue(row, COLUMN_FAMILY_BYTES, qual3, 3, (byte[]) null));</span>
<span class="source-line-no">530</span><span id="line-530"> region.put(p2);</span>
<span class="source-line-no">531</span><span id="line-531"> long expectedSize = sizeOfOnePut * 3;</span>
<span class="source-line-no">532</span><span id="line-532"> Assert.assertEquals(expectedSize, region.getMemStoreDataSize());</span>
<span class="source-line-no">533</span><span id="line-533"> // Do a successful flush. It will clear the snapshot only. Thats how flushes work.</span>
<span class="source-line-no">534</span><span id="line-534"> // If already a snapshot, we clear it else we move the memstore to be snapshot and flush</span>
<span class="source-line-no">535</span><span id="line-535"> // it</span>
<span class="source-line-no">536</span><span id="line-536"> region.flush(true);</span>
<span class="source-line-no">537</span><span id="line-537"> // Make sure our memory accounting is right.</span>
<span class="source-line-no">538</span><span id="line-538"> Assert.assertEquals(sizeOfOnePut * 2, region.getMemStoreDataSize());</span>
<span class="source-line-no">539</span><span id="line-539"> } finally {</span>
<span class="source-line-no">540</span><span id="line-540"> HBaseTestingUtil.closeRegionAndWAL(region);</span>
<span class="source-line-no">541</span><span id="line-541"> }</span>
<span class="source-line-no">542</span><span id="line-542"> return null;</span>
<span class="source-line-no">543</span><span id="line-543"> }</span>
<span class="source-line-no">544</span><span id="line-544"> });</span>
<span class="source-line-no">545</span><span id="line-545"> FileSystem.closeAllForUGI(user.getUGI());</span>
<span class="source-line-no">546</span><span id="line-546"> }</span>
<span class="source-line-no">547</span><span id="line-547"></span>
<span class="source-line-no">548</span><span id="line-548"> @Test</span>
<span class="source-line-no">549</span><span id="line-549"> public void testCloseWithFailingFlush() throws Exception {</span>
<span class="source-line-no">550</span><span id="line-550"> final Configuration conf = HBaseConfiguration.create(CONF);</span>
<span class="source-line-no">551</span><span id="line-551"> final WAL wal = createWALCompatibleWithFaultyFileSystem(method, conf, tableName);</span>
<span class="source-line-no">552</span><span id="line-552"> // Only retry once.</span>
<span class="source-line-no">553</span><span id="line-553"> conf.setInt("hbase.hstore.flush.retries.number", 1);</span>
<span class="source-line-no">554</span><span id="line-554"> final User user = User.createUserForTesting(conf, this.method, new String[] { "foo" });</span>
<span class="source-line-no">555</span><span id="line-555"> // Inject our faulty LocalFileSystem</span>
<span class="source-line-no">556</span><span id="line-556"> conf.setClass("fs.file.impl", FaultyFileSystem.class, FileSystem.class);</span>
<span class="source-line-no">557</span><span id="line-557"> user.runAs(new PrivilegedExceptionAction&lt;Object&gt;() {</span>
<span class="source-line-no">558</span><span id="line-558"> @Override</span>
<span class="source-line-no">559</span><span id="line-559"> public Object run() throws Exception {</span>
<span class="source-line-no">560</span><span id="line-560"> // Make sure it worked (above is sensitive to caching details in hadoop core)</span>
<span class="source-line-no">561</span><span id="line-561"> FileSystem fs = FileSystem.get(conf);</span>
<span class="source-line-no">562</span><span id="line-562"> Assert.assertEquals(FaultyFileSystem.class, fs.getClass());</span>
<span class="source-line-no">563</span><span id="line-563"> FaultyFileSystem ffs = (FaultyFileSystem) fs;</span>
<span class="source-line-no">564</span><span id="line-564"> HRegion region = null;</span>
<span class="source-line-no">565</span><span id="line-565"> try {</span>
<span class="source-line-no">566</span><span id="line-566"> // Initialize region</span>
<span class="source-line-no">567</span><span id="line-567"> region = initHRegion(tableName, null, null, CONF, false, Durability.SYNC_WAL, wal,</span>
<span class="source-line-no">568</span><span id="line-568"> COLUMN_FAMILY_BYTES);</span>
<span class="source-line-no">569</span><span id="line-569"> long size = region.getMemStoreDataSize();</span>
<span class="source-line-no">570</span><span id="line-570"> Assert.assertEquals(0, size);</span>
<span class="source-line-no">571</span><span id="line-571"> // Put one item into memstore. Measure the size of one item in memstore.</span>
<span class="source-line-no">572</span><span id="line-572"> Put p1 = new Put(row);</span>
<span class="source-line-no">573</span><span id="line-573"> p1.add(new KeyValue(row, COLUMN_FAMILY_BYTES, qual1, 1, (byte[]) null));</span>
<span class="source-line-no">574</span><span id="line-574"> region.put(p1);</span>
<span class="source-line-no">575</span><span id="line-575"> // Manufacture an outstanding snapshot -- fake a failed flush by doing prepare step only.</span>
<span class="source-line-no">576</span><span id="line-576"> HStore store = region.getStore(COLUMN_FAMILY_BYTES);</span>
<span class="source-line-no">577</span><span id="line-577"> StoreFlushContext storeFlushCtx =</span>
<span class="source-line-no">578</span><span id="line-578"> store.createFlushContext(12345, FlushLifeCycleTracker.DUMMY);</span>
<span class="source-line-no">579</span><span id="line-579"> storeFlushCtx.prepare();</span>
<span class="source-line-no">580</span><span id="line-580"> // Now add two entries to the foreground memstore.</span>
<span class="source-line-no">581</span><span id="line-581"> Put p2 = new Put(row);</span>
<span class="source-line-no">582</span><span id="line-582"> p2.add(new KeyValue(row, COLUMN_FAMILY_BYTES, qual2, 2, (byte[]) null));</span>
<span class="source-line-no">583</span><span id="line-583"> p2.add(new KeyValue(row, COLUMN_FAMILY_BYTES, qual3, 3, (byte[]) null));</span>
<span class="source-line-no">584</span><span id="line-584"> region.put(p2);</span>
<span class="source-line-no">585</span><span id="line-585"> // Now try close on top of a failing flush.</span>
<span class="source-line-no">586</span><span id="line-586"> HBaseTestingUtil.closeRegionAndWAL(region);</span>
<span class="source-line-no">587</span><span id="line-587"> region = null;</span>
<span class="source-line-no">588</span><span id="line-588"> fail();</span>
<span class="source-line-no">589</span><span id="line-589"> } catch (DroppedSnapshotException dse) {</span>
<span class="source-line-no">590</span><span id="line-590"> // Expected</span>
<span class="source-line-no">591</span><span id="line-591"> LOG.info("Expected DroppedSnapshotException");</span>
<span class="source-line-no">592</span><span id="line-592"> } finally {</span>
<span class="source-line-no">593</span><span id="line-593"> // Make it so all writes succeed from here on out so can close clean</span>
<span class="source-line-no">594</span><span id="line-594"> ffs.fault.set(false);</span>
<span class="source-line-no">595</span><span id="line-595"> HBaseTestingUtil.closeRegionAndWAL(region);</span>
<span class="source-line-no">596</span><span id="line-596"> }</span>
<span class="source-line-no">597</span><span id="line-597"> return null;</span>
<span class="source-line-no">598</span><span id="line-598"> }</span>
<span class="source-line-no">599</span><span id="line-599"> });</span>
<span class="source-line-no">600</span><span id="line-600"> FileSystem.closeAllForUGI(user.getUGI());</span>
<span class="source-line-no">601</span><span id="line-601"> }</span>
<span class="source-line-no">602</span><span id="line-602"></span>
<span class="source-line-no">603</span><span id="line-603"> @Test</span>
<span class="source-line-no">604</span><span id="line-604"> public void testCompactionAffectedByScanners() throws Exception {</span>
<span class="source-line-no">605</span><span id="line-605"> byte[] family = Bytes.toBytes("family");</span>
<span class="source-line-no">606</span><span id="line-606"> this.region = initHRegion(tableName, method, CONF, family);</span>
<span class="source-line-no">607</span><span id="line-607"></span>
<span class="source-line-no">608</span><span id="line-608"> Put put = new Put(Bytes.toBytes("r1"));</span>
<span class="source-line-no">609</span><span id="line-609"> put.addColumn(family, Bytes.toBytes("q1"), Bytes.toBytes("v1"));</span>
<span class="source-line-no">610</span><span id="line-610"> region.put(put);</span>
<span class="source-line-no">611</span><span id="line-611"> region.flush(true);</span>
<span class="source-line-no">612</span><span id="line-612"></span>
<span class="source-line-no">613</span><span id="line-613"> Scan scan = new Scan();</span>
<span class="source-line-no">614</span><span id="line-614"> scan.readVersions(3);</span>
<span class="source-line-no">615</span><span id="line-615"> // open the first scanner</span>
<span class="source-line-no">616</span><span id="line-616"> try (RegionScanner scanner1 = region.getScanner(scan)) {</span>
<span class="source-line-no">617</span><span id="line-617"> Delete delete = new Delete(Bytes.toBytes("r1"));</span>
<span class="source-line-no">618</span><span id="line-618"> region.delete(delete);</span>
<span class="source-line-no">619</span><span id="line-619"> region.flush(true);</span>
<span class="source-line-no">620</span><span id="line-620"> // open the second scanner</span>
<span class="source-line-no">621</span><span id="line-621"> try (RegionScanner scanner2 = region.getScanner(scan)) {</span>
<span class="source-line-no">622</span><span id="line-622"> List&lt;Cell&gt; results = new ArrayList&lt;&gt;();</span>
<span class="source-line-no">623</span><span id="line-623"></span>
<span class="source-line-no">624</span><span id="line-624"> LOG.info("Smallest read point:" + region.getSmallestReadPoint());</span>
<span class="source-line-no">625</span><span id="line-625"></span>
<span class="source-line-no">626</span><span id="line-626"> // make a major compaction</span>
<span class="source-line-no">627</span><span id="line-627"> region.compact(true);</span>
<span class="source-line-no">628</span><span id="line-628"></span>
<span class="source-line-no">629</span><span id="line-629"> // open the third scanner</span>
<span class="source-line-no">630</span><span id="line-630"> try (RegionScanner scanner3 = region.getScanner(scan)) {</span>
<span class="source-line-no">631</span><span id="line-631"> // get data from scanner 1, 2, 3 after major compaction</span>
<span class="source-line-no">632</span><span id="line-632"> scanner1.next(results);</span>
<span class="source-line-no">633</span><span id="line-633"> LOG.info(results.toString());</span>
<span class="source-line-no">634</span><span id="line-634"> assertEquals(1, results.size());</span>
<span class="source-line-no">635</span><span id="line-635"></span>
<span class="source-line-no">636</span><span id="line-636"> results.clear();</span>
<span class="source-line-no">637</span><span id="line-637"> scanner2.next(results);</span>
<span class="source-line-no">638</span><span id="line-638"> LOG.info(results.toString());</span>
<span class="source-line-no">639</span><span id="line-639"> assertEquals(0, results.size());</span>
<span class="source-line-no">640</span><span id="line-640"></span>
<span class="source-line-no">641</span><span id="line-641"> results.clear();</span>
<span class="source-line-no">642</span><span id="line-642"> scanner3.next(results);</span>
<span class="source-line-no">643</span><span id="line-643"> LOG.info(results.toString());</span>
<span class="source-line-no">644</span><span id="line-644"> assertEquals(0, results.size());</span>
<span class="source-line-no">645</span><span id="line-645"> }</span>
<span class="source-line-no">646</span><span id="line-646"> }</span>
<span class="source-line-no">647</span><span id="line-647"> }</span>
<span class="source-line-no">648</span><span id="line-648"> }</span>
<span class="source-line-no">649</span><span id="line-649"></span>
<span class="source-line-no">650</span><span id="line-650"> @Test</span>
<span class="source-line-no">651</span><span id="line-651"> public void testToShowNPEOnRegionScannerReseek() throws Exception {</span>
<span class="source-line-no">652</span><span id="line-652"> byte[] family = Bytes.toBytes("family");</span>
<span class="source-line-no">653</span><span id="line-653"> this.region = initHRegion(tableName, method, CONF, family);</span>
<span class="source-line-no">654</span><span id="line-654"></span>
<span class="source-line-no">655</span><span id="line-655"> Put put = new Put(Bytes.toBytes("r1"));</span>
<span class="source-line-no">656</span><span id="line-656"> put.addColumn(family, Bytes.toBytes("q1"), Bytes.toBytes("v1"));</span>
<span class="source-line-no">657</span><span id="line-657"> region.put(put);</span>
<span class="source-line-no">658</span><span id="line-658"> put = new Put(Bytes.toBytes("r2"));</span>
<span class="source-line-no">659</span><span id="line-659"> put.addColumn(family, Bytes.toBytes("q1"), Bytes.toBytes("v1"));</span>
<span class="source-line-no">660</span><span id="line-660"> region.put(put);</span>
<span class="source-line-no">661</span><span id="line-661"> region.flush(true);</span>
<span class="source-line-no">662</span><span id="line-662"></span>
<span class="source-line-no">663</span><span id="line-663"> Scan scan = new Scan();</span>
<span class="source-line-no">664</span><span id="line-664"> scan.readVersions(3);</span>
<span class="source-line-no">665</span><span id="line-665"> // open the first scanner</span>
<span class="source-line-no">666</span><span id="line-666"> try (RegionScanner scanner1 = region.getScanner(scan)) {</span>
<span class="source-line-no">667</span><span id="line-667"> LOG.info("Smallest read point:" + region.getSmallestReadPoint());</span>
<span class="source-line-no">668</span><span id="line-668"></span>
<span class="source-line-no">669</span><span id="line-669"> region.compact(true);</span>
<span class="source-line-no">670</span><span id="line-670"></span>
<span class="source-line-no">671</span><span id="line-671"> scanner1.reseek(Bytes.toBytes("r2"));</span>
<span class="source-line-no">672</span><span id="line-672"> List&lt;Cell&gt; results = new ArrayList&lt;&gt;();</span>
<span class="source-line-no">673</span><span id="line-673"> scanner1.next(results);</span>
<span class="source-line-no">674</span><span id="line-674"> Cell keyValue = results.get(0);</span>
<span class="source-line-no">675</span><span id="line-675"> assertTrue(Bytes.compareTo(CellUtil.cloneRow(keyValue), Bytes.toBytes("r2")) == 0);</span>
<span class="source-line-no">676</span><span id="line-676"> scanner1.close();</span>
<span class="source-line-no">677</span><span id="line-677"> }</span>
<span class="source-line-no">678</span><span id="line-678"> }</span>
<span class="source-line-no">679</span><span id="line-679"></span>
<span class="source-line-no">680</span><span id="line-680"> @Test</span>
<span class="source-line-no">681</span><span id="line-681"> public void testArchiveRecoveredEditsReplay() throws Exception {</span>
<span class="source-line-no">682</span><span id="line-682"> byte[] family = Bytes.toBytes("family");</span>
<span class="source-line-no">683</span><span id="line-683"> this.region = initHRegion(tableName, method, CONF, family);</span>
<span class="source-line-no">684</span><span id="line-684"> final WALFactory wals = new WALFactory(CONF, method);</span>
<span class="source-line-no">685</span><span id="line-685"> try {</span>
<span class="source-line-no">686</span><span id="line-686"> Path regiondir = region.getRegionFileSystem().getRegionDir();</span>
<span class="source-line-no">687</span><span id="line-687"> FileSystem fs = region.getRegionFileSystem().getFileSystem();</span>
<span class="source-line-no">688</span><span id="line-688"> byte[] regionName = region.getRegionInfo().getEncodedNameAsBytes();</span>
<span class="source-line-no">689</span><span id="line-689"></span>
<span class="source-line-no">690</span><span id="line-690"> Path recoveredEditsDir = WALSplitUtil.getRegionDirRecoveredEditsDir(regiondir);</span>
<span class="source-line-no">691</span><span id="line-691"></span>
<span class="source-line-no">692</span><span id="line-692"> long maxSeqId = 1050;</span>
<span class="source-line-no">693</span><span id="line-693"> long minSeqId = 1000;</span>
<span class="source-line-no">694</span><span id="line-694"></span>
<span class="source-line-no">695</span><span id="line-695"> for (long i = minSeqId; i &lt;= maxSeqId; i += 10) {</span>
<span class="source-line-no">696</span><span id="line-696"> Path recoveredEdits = new Path(recoveredEditsDir, String.format("%019d", i));</span>
<span class="source-line-no">697</span><span id="line-697"> fs.create(recoveredEdits);</span>
<span class="source-line-no">698</span><span id="line-698"> WALProvider.Writer writer = wals.createRecoveredEditsWriter(fs, recoveredEdits);</span>
<span class="source-line-no">699</span><span id="line-699"></span>
<span class="source-line-no">700</span><span id="line-700"> long time = System.nanoTime();</span>
<span class="source-line-no">701</span><span id="line-701"> WALEdit edit = new WALEdit();</span>
<span class="source-line-no">702</span><span id="line-702"> edit.add(</span>
<span class="source-line-no">703</span><span id="line-703"> new KeyValue(row, family, Bytes.toBytes(i), time, KeyValue.Type.Put, Bytes.toBytes(i)));</span>
<span class="source-line-no">704</span><span id="line-704"> writer.append(new WAL.Entry(</span>
<span class="source-line-no">705</span><span id="line-705"> new WALKeyImpl(regionName, tableName, i, time, HConstants.DEFAULT_CLUSTER_ID), edit));</span>
<span class="source-line-no">706</span><span id="line-706"></span>
<span class="source-line-no">707</span><span id="line-707"> writer.close();</span>
<span class="source-line-no">708</span><span id="line-708"> }</span>
<span class="source-line-no">709</span><span id="line-709"> MonitoredTask status = TaskMonitor.get().createStatus(method);</span>
<span class="source-line-no">710</span><span id="line-710"> Map&lt;byte[], Long&gt; maxSeqIdInStores = new TreeMap&lt;&gt;(Bytes.BYTES_COMPARATOR);</span>
<span class="source-line-no">711</span><span id="line-711"> for (HStore store : region.getStores()) {</span>
<span class="source-line-no">712</span><span id="line-712"> maxSeqIdInStores.put(Bytes.toBytes(store.getColumnFamilyName()), minSeqId - 1);</span>
<span class="source-line-no">713</span><span id="line-713"> }</span>
<span class="source-line-no">714</span><span id="line-714"> CONF.set("hbase.region.archive.recovered.edits", "true");</span>
<span class="source-line-no">715</span><span id="line-715"> CONF.set(CommonFSUtils.HBASE_WAL_DIR, "/custom_wal_dir");</span>
<span class="source-line-no">716</span><span id="line-716"> long seqId = region.replayRecoveredEditsIfAny(maxSeqIdInStores, null, status);</span>
<span class="source-line-no">717</span><span id="line-717"> assertEquals(maxSeqId, seqId);</span>
<span class="source-line-no">718</span><span id="line-718"> region.getMVCC().advanceTo(seqId);</span>
<span class="source-line-no">719</span><span id="line-719"> String fakeFamilyName = recoveredEditsDir.getName();</span>
<span class="source-line-no">720</span><span id="line-720"> Path rootDir = new Path(CONF.get(HConstants.HBASE_DIR));</span>
<span class="source-line-no">721</span><span id="line-721"> Path storeArchiveDir = HFileArchiveUtil.getStoreArchivePathForRootDir(rootDir,</span>
<span class="source-line-no">722</span><span id="line-722"> region.getRegionInfo(), Bytes.toBytes(fakeFamilyName));</span>
<span class="source-line-no">723</span><span id="line-723"> FileStatus[] list = TEST_UTIL.getTestFileSystem().listStatus(storeArchiveDir);</span>
<span class="source-line-no">724</span><span id="line-724"> assertEquals(6, list.length);</span>
<span class="source-line-no">725</span><span id="line-725"> } finally {</span>
<span class="source-line-no">726</span><span id="line-726"> CONF.set("hbase.region.archive.recovered.edits", "false");</span>
<span class="source-line-no">727</span><span id="line-727"> CONF.set(CommonFSUtils.HBASE_WAL_DIR, "");</span>
<span class="source-line-no">728</span><span id="line-728"> HBaseTestingUtil.closeRegionAndWAL(this.region);</span>
<span class="source-line-no">729</span><span id="line-729"> this.region = null;</span>
<span class="source-line-no">730</span><span id="line-730"> wals.close();</span>
<span class="source-line-no">731</span><span id="line-731"> }</span>
<span class="source-line-no">732</span><span id="line-732"> }</span>
<span class="source-line-no">733</span><span id="line-733"></span>
<span class="source-line-no">734</span><span id="line-734"> @Test</span>
<span class="source-line-no">735</span><span id="line-735"> public void testSkipRecoveredEditsReplay() throws Exception {</span>
<span class="source-line-no">736</span><span id="line-736"> byte[] family = Bytes.toBytes("family");</span>
<span class="source-line-no">737</span><span id="line-737"> this.region = initHRegion(tableName, method, CONF, family);</span>
<span class="source-line-no">738</span><span id="line-738"> final WALFactory wals = new WALFactory(CONF, method);</span>
<span class="source-line-no">739</span><span id="line-739"> try {</span>
<span class="source-line-no">740</span><span id="line-740"> Path regiondir = region.getRegionFileSystem().getRegionDir();</span>
<span class="source-line-no">741</span><span id="line-741"> FileSystem fs = region.getRegionFileSystem().getFileSystem();</span>
<span class="source-line-no">742</span><span id="line-742"> byte[] regionName = region.getRegionInfo().getEncodedNameAsBytes();</span>
<span class="source-line-no">743</span><span id="line-743"></span>
<span class="source-line-no">744</span><span id="line-744"> Path recoveredEditsDir = WALSplitUtil.getRegionDirRecoveredEditsDir(regiondir);</span>
<span class="source-line-no">745</span><span id="line-745"></span>
<span class="source-line-no">746</span><span id="line-746"> long maxSeqId = 1050;</span>
<span class="source-line-no">747</span><span id="line-747"> long minSeqId = 1000;</span>
<span class="source-line-no">748</span><span id="line-748"></span>
<span class="source-line-no">749</span><span id="line-749"> for (long i = minSeqId; i &lt;= maxSeqId; i += 10) {</span>
<span class="source-line-no">750</span><span id="line-750"> Path recoveredEdits = new Path(recoveredEditsDir, String.format("%019d", i));</span>
<span class="source-line-no">751</span><span id="line-751"> fs.create(recoveredEdits);</span>
<span class="source-line-no">752</span><span id="line-752"> WALProvider.Writer writer = wals.createRecoveredEditsWriter(fs, recoveredEdits);</span>
<span class="source-line-no">753</span><span id="line-753"></span>
<span class="source-line-no">754</span><span id="line-754"> long time = System.nanoTime();</span>
<span class="source-line-no">755</span><span id="line-755"> WALEdit edit = new WALEdit();</span>
<span class="source-line-no">756</span><span id="line-756"> edit.add(</span>
<span class="source-line-no">757</span><span id="line-757"> new KeyValue(row, family, Bytes.toBytes(i), time, KeyValue.Type.Put, Bytes.toBytes(i)));</span>
<span class="source-line-no">758</span><span id="line-758"> writer.append(new WAL.Entry(</span>
<span class="source-line-no">759</span><span id="line-759"> new WALKeyImpl(regionName, tableName, i, time, HConstants.DEFAULT_CLUSTER_ID), edit));</span>
<span class="source-line-no">760</span><span id="line-760"></span>
<span class="source-line-no">761</span><span id="line-761"> writer.close();</span>
<span class="source-line-no">762</span><span id="line-762"> }</span>
<span class="source-line-no">763</span><span id="line-763"> MonitoredTask status = TaskMonitor.get().createStatus(method);</span>
<span class="source-line-no">764</span><span id="line-764"> Map&lt;byte[], Long&gt; maxSeqIdInStores = new TreeMap&lt;&gt;(Bytes.BYTES_COMPARATOR);</span>
<span class="source-line-no">765</span><span id="line-765"> for (HStore store : region.getStores()) {</span>
<span class="source-line-no">766</span><span id="line-766"> maxSeqIdInStores.put(Bytes.toBytes(store.getColumnFamilyName()), minSeqId - 1);</span>
<span class="source-line-no">767</span><span id="line-767"> }</span>
<span class="source-line-no">768</span><span id="line-768"> long seqId = region.replayRecoveredEditsIfAny(maxSeqIdInStores, null, status);</span>
<span class="source-line-no">769</span><span id="line-769"> assertEquals(maxSeqId, seqId);</span>
<span class="source-line-no">770</span><span id="line-770"> region.getMVCC().advanceTo(seqId);</span>
<span class="source-line-no">771</span><span id="line-771"> Get get = new Get(row);</span>
<span class="source-line-no">772</span><span id="line-772"> Result result = region.get(get);</span>
<span class="source-line-no">773</span><span id="line-773"> for (long i = minSeqId; i &lt;= maxSeqId; i += 10) {</span>
<span class="source-line-no">774</span><span id="line-774"> List&lt;Cell&gt; kvs = result.getColumnCells(family, Bytes.toBytes(i));</span>
<span class="source-line-no">775</span><span id="line-775"> assertEquals(1, kvs.size());</span>
<span class="source-line-no">776</span><span id="line-776"> assertArrayEquals(Bytes.toBytes(i), CellUtil.cloneValue(kvs.get(0)));</span>
<span class="source-line-no">777</span><span id="line-777"> }</span>
<span class="source-line-no">778</span><span id="line-778"> } finally {</span>
<span class="source-line-no">779</span><span id="line-779"> HBaseTestingUtil.closeRegionAndWAL(this.region);</span>
<span class="source-line-no">780</span><span id="line-780"> this.region = null;</span>
<span class="source-line-no">781</span><span id="line-781"> wals.close();</span>
<span class="source-line-no">782</span><span id="line-782"> }</span>
<span class="source-line-no">783</span><span id="line-783"> }</span>
<span class="source-line-no">784</span><span id="line-784"></span>
<span class="source-line-no">785</span><span id="line-785"> @Test</span>
<span class="source-line-no">786</span><span id="line-786"> public void testSkipRecoveredEditsReplaySomeIgnored() throws Exception {</span>
<span class="source-line-no">787</span><span id="line-787"> byte[] family = Bytes.toBytes("family");</span>
<span class="source-line-no">788</span><span id="line-788"> this.region = initHRegion(tableName, method, CONF, family);</span>
<span class="source-line-no">789</span><span id="line-789"> final WALFactory wals = new WALFactory(CONF, method);</span>
<span class="source-line-no">790</span><span id="line-790"> try {</span>
<span class="source-line-no">791</span><span id="line-791"> Path regiondir = region.getRegionFileSystem().getRegionDir();</span>
<span class="source-line-no">792</span><span id="line-792"> FileSystem fs = region.getRegionFileSystem().getFileSystem();</span>
<span class="source-line-no">793</span><span id="line-793"> byte[] regionName = region.getRegionInfo().getEncodedNameAsBytes();</span>
<span class="source-line-no">794</span><span id="line-794"></span>
<span class="source-line-no">795</span><span id="line-795"> Path recoveredEditsDir = WALSplitUtil.getRegionDirRecoveredEditsDir(regiondir);</span>
<span class="source-line-no">796</span><span id="line-796"></span>
<span class="source-line-no">797</span><span id="line-797"> long maxSeqId = 1050;</span>
<span class="source-line-no">798</span><span id="line-798"> long minSeqId = 1000;</span>
<span class="source-line-no">799</span><span id="line-799"></span>
<span class="source-line-no">800</span><span id="line-800"> for (long i = minSeqId; i &lt;= maxSeqId; i += 10) {</span>
<span class="source-line-no">801</span><span id="line-801"> Path recoveredEdits = new Path(recoveredEditsDir, String.format("%019d", i));</span>
<span class="source-line-no">802</span><span id="line-802"> fs.create(recoveredEdits);</span>
<span class="source-line-no">803</span><span id="line-803"> WALProvider.Writer writer = wals.createRecoveredEditsWriter(fs, recoveredEdits);</span>
<span class="source-line-no">804</span><span id="line-804"></span>
<span class="source-line-no">805</span><span id="line-805"> long time = System.nanoTime();</span>
<span class="source-line-no">806</span><span id="line-806"> WALEdit edit = new WALEdit();</span>
<span class="source-line-no">807</span><span id="line-807"> edit.add(</span>
<span class="source-line-no">808</span><span id="line-808"> new KeyValue(row, family, Bytes.toBytes(i), time, KeyValue.Type.Put, Bytes.toBytes(i)));</span>
<span class="source-line-no">809</span><span id="line-809"> writer.append(new WAL.Entry(</span>
<span class="source-line-no">810</span><span id="line-810"> new WALKeyImpl(regionName, tableName, i, time, HConstants.DEFAULT_CLUSTER_ID), edit));</span>
<span class="source-line-no">811</span><span id="line-811"></span>
<span class="source-line-no">812</span><span id="line-812"> writer.close();</span>
<span class="source-line-no">813</span><span id="line-813"> }</span>
<span class="source-line-no">814</span><span id="line-814"> long recoverSeqId = 1030;</span>
<span class="source-line-no">815</span><span id="line-815"> MonitoredTask status = TaskMonitor.get().createStatus(method);</span>
<span class="source-line-no">816</span><span id="line-816"> Map&lt;byte[], Long&gt; maxSeqIdInStores = new TreeMap&lt;&gt;(Bytes.BYTES_COMPARATOR);</span>
<span class="source-line-no">817</span><span id="line-817"> for (HStore store : region.getStores()) {</span>
<span class="source-line-no">818</span><span id="line-818"> maxSeqIdInStores.put(Bytes.toBytes(store.getColumnFamilyName()), recoverSeqId - 1);</span>
<span class="source-line-no">819</span><span id="line-819"> }</span>
<span class="source-line-no">820</span><span id="line-820"> long seqId = region.replayRecoveredEditsIfAny(maxSeqIdInStores, null, status);</span>
<span class="source-line-no">821</span><span id="line-821"> assertEquals(maxSeqId, seqId);</span>
<span class="source-line-no">822</span><span id="line-822"> region.getMVCC().advanceTo(seqId);</span>
<span class="source-line-no">823</span><span id="line-823"> Get get = new Get(row);</span>
<span class="source-line-no">824</span><span id="line-824"> Result result = region.get(get);</span>
<span class="source-line-no">825</span><span id="line-825"> for (long i = minSeqId; i &lt;= maxSeqId; i += 10) {</span>
<span class="source-line-no">826</span><span id="line-826"> List&lt;Cell&gt; kvs = result.getColumnCells(family, Bytes.toBytes(i));</span>
<span class="source-line-no">827</span><span id="line-827"> if (i &lt; recoverSeqId) {</span>
<span class="source-line-no">828</span><span id="line-828"> assertEquals(0, kvs.size());</span>
<span class="source-line-no">829</span><span id="line-829"> } else {</span>
<span class="source-line-no">830</span><span id="line-830"> assertEquals(1, kvs.size());</span>
<span class="source-line-no">831</span><span id="line-831"> assertArrayEquals(Bytes.toBytes(i), CellUtil.cloneValue(kvs.get(0)));</span>
<span class="source-line-no">832</span><span id="line-832"> }</span>
<span class="source-line-no">833</span><span id="line-833"> }</span>
<span class="source-line-no">834</span><span id="line-834"> } finally {</span>
<span class="source-line-no">835</span><span id="line-835"> HBaseTestingUtil.closeRegionAndWAL(this.region);</span>
<span class="source-line-no">836</span><span id="line-836"> this.region = null;</span>
<span class="source-line-no">837</span><span id="line-837"> wals.close();</span>
<span class="source-line-no">838</span><span id="line-838"> }</span>
<span class="source-line-no">839</span><span id="line-839"> }</span>
<span class="source-line-no">840</span><span id="line-840"></span>
<span class="source-line-no">841</span><span id="line-841"> @Test</span>
<span class="source-line-no">842</span><span id="line-842"> public void testSkipRecoveredEditsReplayAllIgnored() throws Exception {</span>
<span class="source-line-no">843</span><span id="line-843"> byte[] family = Bytes.toBytes("family");</span>
<span class="source-line-no">844</span><span id="line-844"> this.region = initHRegion(tableName, method, CONF, family);</span>
<span class="source-line-no">845</span><span id="line-845"> Path regiondir = region.getRegionFileSystem().getRegionDir();</span>
<span class="source-line-no">846</span><span id="line-846"> FileSystem fs = region.getRegionFileSystem().getFileSystem();</span>
<span class="source-line-no">847</span><span id="line-847"></span>
<span class="source-line-no">848</span><span id="line-848"> Path recoveredEditsDir = WALSplitUtil.getRegionDirRecoveredEditsDir(regiondir);</span>
<span class="source-line-no">849</span><span id="line-849"> for (int i = 1000; i &lt; 1050; i += 10) {</span>
<span class="source-line-no">850</span><span id="line-850"> Path recoveredEdits = new Path(recoveredEditsDir, String.format("%019d", i));</span>
<span class="source-line-no">851</span><span id="line-851"> FSDataOutputStream dos = fs.create(recoveredEdits);</span>
<span class="source-line-no">852</span><span id="line-852"> dos.writeInt(i);</span>
<span class="source-line-no">853</span><span id="line-853"> dos.close();</span>
<span class="source-line-no">854</span><span id="line-854"> }</span>
<span class="source-line-no">855</span><span id="line-855"> long minSeqId = 2000;</span>
<span class="source-line-no">856</span><span id="line-856"> Path recoveredEdits = new Path(recoveredEditsDir, String.format("%019d", minSeqId - 1));</span>
<span class="source-line-no">857</span><span id="line-857"> FSDataOutputStream dos = fs.create(recoveredEdits);</span>
<span class="source-line-no">858</span><span id="line-858"> dos.close();</span>
<span class="source-line-no">859</span><span id="line-859"></span>
<span class="source-line-no">860</span><span id="line-860"> Map&lt;byte[], Long&gt; maxSeqIdInStores = new TreeMap&lt;&gt;(Bytes.BYTES_COMPARATOR);</span>
<span class="source-line-no">861</span><span id="line-861"> for (HStore store : region.getStores()) {</span>
<span class="source-line-no">862</span><span id="line-862"> maxSeqIdInStores.put(Bytes.toBytes(store.getColumnFamilyName()), minSeqId);</span>
<span class="source-line-no">863</span><span id="line-863"> }</span>
<span class="source-line-no">864</span><span id="line-864"> long seqId = region.replayRecoveredEditsIfAny(maxSeqIdInStores, null, null);</span>
<span class="source-line-no">865</span><span id="line-865"> assertEquals(minSeqId, seqId);</span>
<span class="source-line-no">866</span><span id="line-866"> }</span>
<span class="source-line-no">867</span><span id="line-867"></span>
<span class="source-line-no">868</span><span id="line-868"> @Test</span>
<span class="source-line-no">869</span><span id="line-869"> public void testSkipRecoveredEditsReplayTheLastFileIgnored() throws Exception {</span>
<span class="source-line-no">870</span><span id="line-870"> byte[] family = Bytes.toBytes("family");</span>
<span class="source-line-no">871</span><span id="line-871"> this.region = initHRegion(tableName, method, CONF, family);</span>
<span class="source-line-no">872</span><span id="line-872"> final WALFactory wals = new WALFactory(CONF, method);</span>
<span class="source-line-no">873</span><span id="line-873"> try {</span>
<span class="source-line-no">874</span><span id="line-874"> Path regiondir = region.getRegionFileSystem().getRegionDir();</span>
<span class="source-line-no">875</span><span id="line-875"> FileSystem fs = region.getRegionFileSystem().getFileSystem();</span>
<span class="source-line-no">876</span><span id="line-876"> byte[] regionName = region.getRegionInfo().getEncodedNameAsBytes();</span>
<span class="source-line-no">877</span><span id="line-877"> byte[][] columns = region.getTableDescriptor().getColumnFamilyNames().toArray(new byte[0][]);</span>
<span class="source-line-no">878</span><span id="line-878"></span>
<span class="source-line-no">879</span><span id="line-879"> assertEquals(0, region.getStoreFileList(columns).size());</span>
<span class="source-line-no">880</span><span id="line-880"></span>
<span class="source-line-no">881</span><span id="line-881"> Path recoveredEditsDir = WALSplitUtil.getRegionDirRecoveredEditsDir(regiondir);</span>
<span class="source-line-no">882</span><span id="line-882"></span>
<span class="source-line-no">883</span><span id="line-883"> long maxSeqId = 1050;</span>
<span class="source-line-no">884</span><span id="line-884"> long minSeqId = 1000;</span>
<span class="source-line-no">885</span><span id="line-885"></span>
<span class="source-line-no">886</span><span id="line-886"> for (long i = minSeqId; i &lt;= maxSeqId; i += 10) {</span>
<span class="source-line-no">887</span><span id="line-887"> Path recoveredEdits = new Path(recoveredEditsDir, String.format("%019d", i));</span>
<span class="source-line-no">888</span><span id="line-888"> fs.create(recoveredEdits);</span>
<span class="source-line-no">889</span><span id="line-889"> WALProvider.Writer writer = wals.createRecoveredEditsWriter(fs, recoveredEdits);</span>
<span class="source-line-no">890</span><span id="line-890"></span>
<span class="source-line-no">891</span><span id="line-891"> long time = System.nanoTime();</span>
<span class="source-line-no">892</span><span id="line-892"> WALEdit edit = null;</span>
<span class="source-line-no">893</span><span id="line-893"> if (i == maxSeqId) {</span>
<span class="source-line-no">894</span><span id="line-894"> edit = WALEdit.createCompaction(region.getRegionInfo(),</span>
<span class="source-line-no">895</span><span id="line-895"> CompactionDescriptor.newBuilder().setTableName(ByteString.copyFrom(tableName.getName()))</span>
<span class="source-line-no">896</span><span id="line-896"> .setFamilyName(ByteString.copyFrom(regionName))</span>
<span class="source-line-no">897</span><span id="line-897"> .setEncodedRegionName(ByteString.copyFrom(regionName))</span>
<span class="source-line-no">898</span><span id="line-898"> .setStoreHomeDirBytes(ByteString.copyFrom(Bytes.toBytes(regiondir.toString())))</span>
<span class="source-line-no">899</span><span id="line-899"> .setRegionName(ByteString.copyFrom(region.getRegionInfo().getRegionName())).build());</span>
<span class="source-line-no">900</span><span id="line-900"> } else {</span>
<span class="source-line-no">901</span><span id="line-901"> edit = new WALEdit();</span>
<span class="source-line-no">902</span><span id="line-902"> edit.add(</span>
<span class="source-line-no">903</span><span id="line-903"> new KeyValue(row, family, Bytes.toBytes(i), time, KeyValue.Type.Put, Bytes.toBytes(i)));</span>
<span class="source-line-no">904</span><span id="line-904"> }</span>
<span class="source-line-no">905</span><span id="line-905"> writer.append(new WAL.Entry(</span>
<span class="source-line-no">906</span><span id="line-906"> new WALKeyImpl(regionName, tableName, i, time, HConstants.DEFAULT_CLUSTER_ID), edit));</span>
<span class="source-line-no">907</span><span id="line-907"> writer.close();</span>
<span class="source-line-no">908</span><span id="line-908"> }</span>
<span class="source-line-no">909</span><span id="line-909"></span>
<span class="source-line-no">910</span><span id="line-910"> long recoverSeqId = 1030;</span>
<span class="source-line-no">911</span><span id="line-911"> Map&lt;byte[], Long&gt; maxSeqIdInStores = new TreeMap&lt;&gt;(Bytes.BYTES_COMPARATOR);</span>
<span class="source-line-no">912</span><span id="line-912"> MonitoredTask status = TaskMonitor.get().createStatus(method);</span>
<span class="source-line-no">913</span><span id="line-913"> for (HStore store : region.getStores()) {</span>
<span class="source-line-no">914</span><span id="line-914"> maxSeqIdInStores.put(Bytes.toBytes(store.getColumnFamilyName()), recoverSeqId - 1);</span>
<span class="source-line-no">915</span><span id="line-915"> }</span>
<span class="source-line-no">916</span><span id="line-916"> long seqId = region.replayRecoveredEditsIfAny(maxSeqIdInStores, null, status);</span>
<span class="source-line-no">917</span><span id="line-917"> assertEquals(maxSeqId, seqId);</span>
<span class="source-line-no">918</span><span id="line-918"></span>
<span class="source-line-no">919</span><span id="line-919"> // assert that the files are flushed</span>
<span class="source-line-no">920</span><span id="line-920"> assertEquals(1, region.getStoreFileList(columns).size());</span>
<span class="source-line-no">921</span><span id="line-921"></span>
<span class="source-line-no">922</span><span id="line-922"> } finally {</span>
<span class="source-line-no">923</span><span id="line-923"> HBaseTestingUtil.closeRegionAndWAL(this.region);</span>
<span class="source-line-no">924</span><span id="line-924"> this.region = null;</span>
<span class="source-line-no">925</span><span id="line-925"> wals.close();</span>
<span class="source-line-no">926</span><span id="line-926"> }</span>
<span class="source-line-no">927</span><span id="line-927"> }</span>
<span class="source-line-no">928</span><span id="line-928"></span>
<span class="source-line-no">929</span><span id="line-929"> @Test</span>
<span class="source-line-no">930</span><span id="line-930"> public void testRecoveredEditsReplayCompaction() throws Exception {</span>
<span class="source-line-no">931</span><span id="line-931"> testRecoveredEditsReplayCompaction(false);</span>
<span class="source-line-no">932</span><span id="line-932"> testRecoveredEditsReplayCompaction(true);</span>
<span class="source-line-no">933</span><span id="line-933"> }</span>
<span class="source-line-no">934</span><span id="line-934"></span>
<span class="source-line-no">935</span><span id="line-935"> public void testRecoveredEditsReplayCompaction(boolean mismatchedRegionName) throws Exception {</span>
<span class="source-line-no">936</span><span id="line-936"> CONF.setClass(HConstants.REGION_IMPL, HRegionForTesting.class, Region.class);</span>
<span class="source-line-no">937</span><span id="line-937"> byte[] family = Bytes.toBytes("family");</span>
<span class="source-line-no">938</span><span id="line-938"> this.region = initHRegion(tableName, method, CONF, family);</span>
<span class="source-line-no">939</span><span id="line-939"> final WALFactory wals = new WALFactory(CONF, method);</span>
<span class="source-line-no">940</span><span id="line-940"> try {</span>
<span class="source-line-no">941</span><span id="line-941"> Path regiondir = region.getRegionFileSystem().getRegionDir();</span>
<span class="source-line-no">942</span><span id="line-942"> FileSystem fs = region.getRegionFileSystem().getFileSystem();</span>
<span class="source-line-no">943</span><span id="line-943"> byte[] regionName = region.getRegionInfo().getEncodedNameAsBytes();</span>
<span class="source-line-no">944</span><span id="line-944"></span>
<span class="source-line-no">945</span><span id="line-945"> long maxSeqId = 3;</span>
<span class="source-line-no">946</span><span id="line-946"> long minSeqId = 0;</span>
<span class="source-line-no">947</span><span id="line-947"></span>
<span class="source-line-no">948</span><span id="line-948"> for (long i = minSeqId; i &lt; maxSeqId; i++) {</span>
<span class="source-line-no">949</span><span id="line-949"> Put put = new Put(Bytes.toBytes(i));</span>
<span class="source-line-no">950</span><span id="line-950"> put.addColumn(family, Bytes.toBytes(i), Bytes.toBytes(i));</span>
<span class="source-line-no">951</span><span id="line-951"> region.put(put);</span>
<span class="source-line-no">952</span><span id="line-952"> region.flush(true);</span>
<span class="source-line-no">953</span><span id="line-953"> }</span>
<span class="source-line-no">954</span><span id="line-954"></span>
<span class="source-line-no">955</span><span id="line-955"> // this will create a region with 3 files</span>
<span class="source-line-no">956</span><span id="line-956"> assertEquals(3, region.getStore(family).getStorefilesCount());</span>
<span class="source-line-no">957</span><span id="line-957"> List&lt;Path&gt; storeFiles = new ArrayList&lt;&gt;(3);</span>
<span class="source-line-no">958</span><span id="line-958"> for (HStoreFile sf : region.getStore(family).getStorefiles()) {</span>
<span class="source-line-no">959</span><span id="line-959"> storeFiles.add(sf.getPath());</span>
<span class="source-line-no">960</span><span id="line-960"> }</span>
<span class="source-line-no">961</span><span id="line-961"></span>
<span class="source-line-no">962</span><span id="line-962"> // disable compaction completion</span>
<span class="source-line-no">963</span><span id="line-963"> CONF.setBoolean("hbase.hstore.compaction.complete", false);</span>
<span class="source-line-no">964</span><span id="line-964"> region.compactStores();</span>
<span class="source-line-no">965</span><span id="line-965"></span>
<span class="source-line-no">966</span><span id="line-966"> // ensure that nothing changed</span>
<span class="source-line-no">967</span><span id="line-967"> assertEquals(3, region.getStore(family).getStorefilesCount());</span>
<span class="source-line-no">968</span><span id="line-968"></span>
<span class="source-line-no">969</span><span id="line-969"> // now find the compacted file, and manually add it to the recovered edits</span>
<span class="source-line-no">970</span><span id="line-970"> Path tmpDir = new Path(region.getRegionFileSystem().getTempDir(), Bytes.toString(family));</span>
<span class="source-line-no">971</span><span id="line-971"> FileStatus[] files = CommonFSUtils.listStatus(fs, tmpDir);</span>
<span class="source-line-no">972</span><span id="line-972"> String errorMsg = "Expected to find 1 file in the region temp directory "</span>
<span class="source-line-no">973</span><span id="line-973"> + "from the compaction, could not find any";</span>
<span class="source-line-no">974</span><span id="line-974"> assertNotNull(errorMsg, files);</span>
<span class="source-line-no">975</span><span id="line-975"> assertEquals(errorMsg, 1, files.length);</span>
<span class="source-line-no">976</span><span id="line-976"> // move the file inside region dir</span>
<span class="source-line-no">977</span><span id="line-977"> Path newFile =</span>
<span class="source-line-no">978</span><span id="line-978"> region.getRegionFileSystem().commitStoreFile(Bytes.toString(family), files[0].getPath());</span>
<span class="source-line-no">979</span><span id="line-979"></span>
<span class="source-line-no">980</span><span id="line-980"> byte[] encodedNameAsBytes = this.region.getRegionInfo().getEncodedNameAsBytes();</span>
<span class="source-line-no">981</span><span id="line-981"> byte[] fakeEncodedNameAsBytes = new byte[encodedNameAsBytes.length];</span>
<span class="source-line-no">982</span><span id="line-982"> for (int i = 0; i &lt; encodedNameAsBytes.length; i++) {</span>
<span class="source-line-no">983</span><span id="line-983"> // Mix the byte array to have a new encodedName</span>
<span class="source-line-no">984</span><span id="line-984"> fakeEncodedNameAsBytes[i] = (byte) (encodedNameAsBytes[i] + 1);</span>
<span class="source-line-no">985</span><span id="line-985"> }</span>
<span class="source-line-no">986</span><span id="line-986"></span>
<span class="source-line-no">987</span><span id="line-987"> CompactionDescriptor compactionDescriptor = ProtobufUtil.toCompactionDescriptor(</span>
<span class="source-line-no">988</span><span id="line-988"> this.region.getRegionInfo(), mismatchedRegionName ? fakeEncodedNameAsBytes : null, family,</span>
<span class="source-line-no">989</span><span id="line-989"> storeFiles, Lists.newArrayList(newFile),</span>
<span class="source-line-no">990</span><span id="line-990"> region.getRegionFileSystem().getStoreDir(Bytes.toString(family)));</span>
<span class="source-line-no">991</span><span id="line-991"></span>
<span class="source-line-no">992</span><span id="line-992"> WALUtil.writeCompactionMarker(region.getWAL(), this.region.getReplicationScope(),</span>
<span class="source-line-no">993</span><span id="line-993"> this.region.getRegionInfo(), compactionDescriptor, region.getMVCC(), null);</span>
<span class="source-line-no">994</span><span id="line-994"></span>
<span class="source-line-no">995</span><span id="line-995"> Path recoveredEditsDir = WALSplitUtil.getRegionDirRecoveredEditsDir(regiondir);</span>
<span class="source-line-no">996</span><span id="line-996"></span>
<span class="source-line-no">997</span><span id="line-997"> Path recoveredEdits = new Path(recoveredEditsDir, String.format("%019d", 1000));</span>
<span class="source-line-no">998</span><span id="line-998"> fs.create(recoveredEdits);</span>
<span class="source-line-no">999</span><span id="line-999"> WALProvider.Writer writer = wals.createRecoveredEditsWriter(fs, recoveredEdits);</span>
<span class="source-line-no">1000</span><span id="line-1000"></span>
<span class="source-line-no">1001</span><span id="line-1001"> long time = System.nanoTime();</span>
<span class="source-line-no">1002</span><span id="line-1002"></span>
<span class="source-line-no">1003</span><span id="line-1003"> writer.append(new WAL.Entry(</span>
<span class="source-line-no">1004</span><span id="line-1004"> new WALKeyImpl(regionName, tableName, 10, time, HConstants.DEFAULT_CLUSTER_ID),</span>
<span class="source-line-no">1005</span><span id="line-1005"> WALEdit.createCompaction(region.getRegionInfo(), compactionDescriptor)));</span>
<span class="source-line-no">1006</span><span id="line-1006"> writer.close();</span>
<span class="source-line-no">1007</span><span id="line-1007"></span>
<span class="source-line-no">1008</span><span id="line-1008"> // close the region now, and reopen again</span>
<span class="source-line-no">1009</span><span id="line-1009"> region.getTableDescriptor();</span>
<span class="source-line-no">1010</span><span id="line-1010"> region.getRegionInfo();</span>
<span class="source-line-no">1011</span><span id="line-1011"> HBaseTestingUtil.closeRegionAndWAL(this.region);</span>
<span class="source-line-no">1012</span><span id="line-1012"> try {</span>
<span class="source-line-no">1013</span><span id="line-1013"> region = HRegion.openHRegion(region, null);</span>
<span class="source-line-no">1014</span><span id="line-1014"> } catch (WrongRegionException wre) {</span>
<span class="source-line-no">1015</span><span id="line-1015"> fail("Matching encoded region name should not have produced WrongRegionException");</span>
<span class="source-line-no">1016</span><span id="line-1016"> }</span>
<span class="source-line-no">1017</span><span id="line-1017"></span>
<span class="source-line-no">1018</span><span id="line-1018"> // now check whether we have only one store file, the compacted one</span>
<span class="source-line-no">1019</span><span id="line-1019"> Collection&lt;HStoreFile&gt; sfs = region.getStore(family).getStorefiles();</span>
<span class="source-line-no">1020</span><span id="line-1020"> for (HStoreFile sf : sfs) {</span>
<span class="source-line-no">1021</span><span id="line-1021"> LOG.info(Objects.toString(sf.getPath()));</span>
<span class="source-line-no">1022</span><span id="line-1022"> }</span>
<span class="source-line-no">1023</span><span id="line-1023"> if (!mismatchedRegionName) {</span>
<span class="source-line-no">1024</span><span id="line-1024"> assertEquals(1, region.getStore(family).getStorefilesCount());</span>
<span class="source-line-no">1025</span><span id="line-1025"> }</span>
<span class="source-line-no">1026</span><span id="line-1026"> files = CommonFSUtils.listStatus(fs, tmpDir);</span>
<span class="source-line-no">1027</span><span id="line-1027"> assertTrue("Expected to find 0 files inside " + tmpDir, files == null || files.length == 0);</span>
<span class="source-line-no">1028</span><span id="line-1028"></span>
<span class="source-line-no">1029</span><span id="line-1029"> for (long i = minSeqId; i &lt; maxSeqId; i++) {</span>
<span class="source-line-no">1030</span><span id="line-1030"> Get get = new Get(Bytes.toBytes(i));</span>
<span class="source-line-no">1031</span><span id="line-1031"> Result result = region.get(get);</span>
<span class="source-line-no">1032</span><span id="line-1032"> byte[] value = result.getValue(family, Bytes.toBytes(i));</span>
<span class="source-line-no">1033</span><span id="line-1033"> assertArrayEquals(Bytes.toBytes(i), value);</span>
<span class="source-line-no">1034</span><span id="line-1034"> }</span>
<span class="source-line-no">1035</span><span id="line-1035"> } finally {</span>
<span class="source-line-no">1036</span><span id="line-1036"> HBaseTestingUtil.closeRegionAndWAL(this.region);</span>
<span class="source-line-no">1037</span><span id="line-1037"> this.region = null;</span>
<span class="source-line-no">1038</span><span id="line-1038"> wals.close();</span>
<span class="source-line-no">1039</span><span id="line-1039"> CONF.setClass(HConstants.REGION_IMPL, HRegion.class, Region.class);</span>
<span class="source-line-no">1040</span><span id="line-1040"> }</span>
<span class="source-line-no">1041</span><span id="line-1041"> }</span>
<span class="source-line-no">1042</span><span id="line-1042"></span>
<span class="source-line-no">1043</span><span id="line-1043"> @Test</span>
<span class="source-line-no">1044</span><span id="line-1044"> public void testFlushMarkers() throws Exception {</span>
<span class="source-line-no">1045</span><span id="line-1045"> // tests that flush markers are written to WAL and handled at recovered edits</span>
<span class="source-line-no">1046</span><span id="line-1046"> byte[] family = Bytes.toBytes("family");</span>
<span class="source-line-no">1047</span><span id="line-1047"> Path logDir = TEST_UTIL.getDataTestDirOnTestFS(method + ".log");</span>
<span class="source-line-no">1048</span><span id="line-1048"> final Configuration walConf = new Configuration(TEST_UTIL.getConfiguration());</span>
<span class="source-line-no">1049</span><span id="line-1049"> CommonFSUtils.setRootDir(walConf, logDir);</span>
<span class="source-line-no">1050</span><span id="line-1050"> final WALFactory wals = new WALFactory(walConf, method);</span>
<span class="source-line-no">1051</span><span id="line-1051"> final WAL wal = wals.getWAL(RegionInfoBuilder.newBuilder(tableName).build());</span>
<span class="source-line-no">1052</span><span id="line-1052"></span>
<span class="source-line-no">1053</span><span id="line-1053"> this.region = initHRegion(tableName, HConstants.EMPTY_START_ROW, HConstants.EMPTY_END_ROW, CONF,</span>
<span class="source-line-no">1054</span><span id="line-1054"> false, Durability.USE_DEFAULT, wal, family);</span>
<span class="source-line-no">1055</span><span id="line-1055"> try {</span>
<span class="source-line-no">1056</span><span id="line-1056"> Path regiondir = region.getRegionFileSystem().getRegionDir();</span>
<span class="source-line-no">1057</span><span id="line-1057"> FileSystem fs = region.getRegionFileSystem().getFileSystem();</span>
<span class="source-line-no">1058</span><span id="line-1058"> byte[] regionName = region.getRegionInfo().getEncodedNameAsBytes();</span>
<span class="source-line-no">1059</span><span id="line-1059"></span>
<span class="source-line-no">1060</span><span id="line-1060"> long maxSeqId = 3;</span>
<span class="source-line-no">1061</span><span id="line-1061"> long minSeqId = 0;</span>
<span class="source-line-no">1062</span><span id="line-1062"></span>
<span class="source-line-no">1063</span><span id="line-1063"> for (long i = minSeqId; i &lt; maxSeqId; i++) {</span>
<span class="source-line-no">1064</span><span id="line-1064"> Put put = new Put(Bytes.toBytes(i));</span>
<span class="source-line-no">1065</span><span id="line-1065"> put.addColumn(family, Bytes.toBytes(i), Bytes.toBytes(i));</span>
<span class="source-line-no">1066</span><span id="line-1066"> region.put(put);</span>
<span class="source-line-no">1067</span><span id="line-1067"> region.flush(true);</span>
<span class="source-line-no">1068</span><span id="line-1068"> }</span>
<span class="source-line-no">1069</span><span id="line-1069"></span>
<span class="source-line-no">1070</span><span id="line-1070"> // this will create a region with 3 files from flush</span>
<span class="source-line-no">1071</span><span id="line-1071"> assertEquals(3, region.getStore(family).getStorefilesCount());</span>
<span class="source-line-no">1072</span><span id="line-1072"> List&lt;String&gt; storeFiles = new ArrayList&lt;&gt;(3);</span>
<span class="source-line-no">1073</span><span id="line-1073"> for (HStoreFile sf : region.getStore(family).getStorefiles()) {</span>
<span class="source-line-no">1074</span><span id="line-1074"> storeFiles.add(sf.getPath().getName());</span>
<span class="source-line-no">1075</span><span id="line-1075"> }</span>
<span class="source-line-no">1076</span><span id="line-1076"></span>
<span class="source-line-no">1077</span><span id="line-1077"> // now verify that the flush markers are written</span>
<span class="source-line-no">1078</span><span id="line-1078"> wal.shutdown();</span>
<span class="source-line-no">1079</span><span id="line-1079"> WALStreamReader reader = WALFactory.createStreamReader(fs,</span>
<span class="source-line-no">1080</span><span id="line-1080"> AbstractFSWALProvider.getCurrentFileName(wal), TEST_UTIL.getConfiguration());</span>
<span class="source-line-no">1081</span><span id="line-1081"> try {</span>
<span class="source-line-no">1082</span><span id="line-1082"> List&lt;WAL.Entry&gt; flushDescriptors = new ArrayList&lt;&gt;();</span>
<span class="source-line-no">1083</span><span id="line-1083"> long lastFlushSeqId = -1;</span>
<span class="source-line-no">1084</span><span id="line-1084"> while (true) {</span>
<span class="source-line-no">1085</span><span id="line-1085"> WAL.Entry entry = reader.next();</span>
<span class="source-line-no">1086</span><span id="line-1086"> if (entry == null) {</span>
<span class="source-line-no">1087</span><span id="line-1087"> break;</span>
<span class="source-line-no">1088</span><span id="line-1088"> }</span>
<span class="source-line-no">1089</span><span id="line-1089"> Cell cell = entry.getEdit().getCells().get(0);</span>
<span class="source-line-no">1090</span><span id="line-1090"> if (WALEdit.isMetaEditFamily(cell)) {</span>
<span class="source-line-no">1091</span><span id="line-1091"> FlushDescriptor flushDesc = WALEdit.getFlushDescriptor(cell);</span>
<span class="source-line-no">1092</span><span id="line-1092"> assertNotNull(flushDesc);</span>
<span class="source-line-no">1093</span><span id="line-1093"> assertArrayEquals(tableName.getName(), flushDesc.getTableName().toByteArray());</span>
<span class="source-line-no">1094</span><span id="line-1094"> if (flushDesc.getAction() == FlushAction.START_FLUSH) {</span>
<span class="source-line-no">1095</span><span id="line-1095"> assertTrue(flushDesc.getFlushSequenceNumber() &gt; lastFlushSeqId);</span>
<span class="source-line-no">1096</span><span id="line-1096"> } else if (flushDesc.getAction() == FlushAction.COMMIT_FLUSH) {</span>
<span class="source-line-no">1097</span><span id="line-1097"> assertTrue(flushDesc.getFlushSequenceNumber() == lastFlushSeqId);</span>
<span class="source-line-no">1098</span><span id="line-1098"> }</span>
<span class="source-line-no">1099</span><span id="line-1099"> lastFlushSeqId = flushDesc.getFlushSequenceNumber();</span>
<span class="source-line-no">1100</span><span id="line-1100"> assertArrayEquals(regionName, flushDesc.getEncodedRegionName().toByteArray());</span>
<span class="source-line-no">1101</span><span id="line-1101"> assertEquals(1, flushDesc.getStoreFlushesCount()); // only one store</span>
<span class="source-line-no">1102</span><span id="line-1102"> StoreFlushDescriptor storeFlushDesc = flushDesc.getStoreFlushes(0);</span>
<span class="source-line-no">1103</span><span id="line-1103"> assertArrayEquals(family, storeFlushDesc.getFamilyName().toByteArray());</span>
<span class="source-line-no">1104</span><span id="line-1104"> assertEquals("family", storeFlushDesc.getStoreHomeDir());</span>
<span class="source-line-no">1105</span><span id="line-1105"> if (flushDesc.getAction() == FlushAction.START_FLUSH) {</span>
<span class="source-line-no">1106</span><span id="line-1106"> assertEquals(0, storeFlushDesc.getFlushOutputCount());</span>
<span class="source-line-no">1107</span><span id="line-1107"> } else {</span>
<span class="source-line-no">1108</span><span id="line-1108"> assertEquals(1, storeFlushDesc.getFlushOutputCount()); // only one file from flush</span>
<span class="source-line-no">1109</span><span id="line-1109"> assertTrue(storeFiles.contains(storeFlushDesc.getFlushOutput(0)));</span>
<span class="source-line-no">1110</span><span id="line-1110"> }</span>
<span class="source-line-no">1111</span><span id="line-1111"></span>
<span class="source-line-no">1112</span><span id="line-1112"> flushDescriptors.add(entry);</span>
<span class="source-line-no">1113</span><span id="line-1113"> }</span>
<span class="source-line-no">1114</span><span id="line-1114"> }</span>
<span class="source-line-no">1115</span><span id="line-1115"></span>
<span class="source-line-no">1116</span><span id="line-1116"> assertEquals(3 * 2, flushDescriptors.size()); // START_FLUSH and COMMIT_FLUSH per flush</span>
<span class="source-line-no">1117</span><span id="line-1117"></span>
<span class="source-line-no">1118</span><span id="line-1118"> // now write those markers to the recovered edits again.</span>
<span class="source-line-no">1119</span><span id="line-1119"></span>
<span class="source-line-no">1120</span><span id="line-1120"> Path recoveredEditsDir = WALSplitUtil.getRegionDirRecoveredEditsDir(regiondir);</span>
<span class="source-line-no">1121</span><span id="line-1121"></span>
<span class="source-line-no">1122</span><span id="line-1122"> Path recoveredEdits = new Path(recoveredEditsDir, String.format("%019d", 1000));</span>
<span class="source-line-no">1123</span><span id="line-1123"> fs.create(recoveredEdits);</span>
<span class="source-line-no">1124</span><span id="line-1124"> WALProvider.Writer writer = wals.createRecoveredEditsWriter(fs, recoveredEdits);</span>
<span class="source-line-no">1125</span><span id="line-1125"></span>
<span class="source-line-no">1126</span><span id="line-1126"> for (WAL.Entry entry : flushDescriptors) {</span>
<span class="source-line-no">1127</span><span id="line-1127"> writer.append(entry);</span>
<span class="source-line-no">1128</span><span id="line-1128"> }</span>
<span class="source-line-no">1129</span><span id="line-1129"> writer.close();</span>
<span class="source-line-no">1130</span><span id="line-1130"> } finally {</span>
<span class="source-line-no">1131</span><span id="line-1131"> reader.close();</span>
<span class="source-line-no">1132</span><span id="line-1132"> }</span>
<span class="source-line-no">1133</span><span id="line-1133"></span>
<span class="source-line-no">1134</span><span id="line-1134"> // close the region now, and reopen again</span>
<span class="source-line-no">1135</span><span id="line-1135"> HBaseTestingUtil.closeRegionAndWAL(this.region);</span>
<span class="source-line-no">1136</span><span id="line-1136"> region = HRegion.openHRegion(region, null);</span>
<span class="source-line-no">1137</span><span id="line-1137"></span>
<span class="source-line-no">1138</span><span id="line-1138"> // now check whether we have can read back the data from region</span>
<span class="source-line-no">1139</span><span id="line-1139"> for (long i = minSeqId; i &lt; maxSeqId; i++) {</span>
<span class="source-line-no">1140</span><span id="line-1140"> Get get = new Get(Bytes.toBytes(i));</span>
<span class="source-line-no">1141</span><span id="line-1141"> Result result = region.get(get);</span>
<span class="source-line-no">1142</span><span id="line-1142"> byte[] value = result.getValue(family, Bytes.toBytes(i));</span>
<span class="source-line-no">1143</span><span id="line-1143"> assertArrayEquals(Bytes.toBytes(i), value);</span>
<span class="source-line-no">1144</span><span id="line-1144"> }</span>
<span class="source-line-no">1145</span><span id="line-1145"> } finally {</span>
<span class="source-line-no">1146</span><span id="line-1146"> HBaseTestingUtil.closeRegionAndWAL(this.region);</span>
<span class="source-line-no">1147</span><span id="line-1147"> this.region = null;</span>
<span class="source-line-no">1148</span><span id="line-1148"> wals.close();</span>
<span class="source-line-no">1149</span><span id="line-1149"> }</span>
<span class="source-line-no">1150</span><span id="line-1150"> }</span>
<span class="source-line-no">1151</span><span id="line-1151"></span>
<span class="source-line-no">1152</span><span id="line-1152"> static class IsFlushWALMarker implements ArgumentMatcher&lt;WALEdit&gt; {</span>
<span class="source-line-no">1153</span><span id="line-1153"> volatile FlushAction[] actions;</span>
<span class="source-line-no">1154</span><span id="line-1154"></span>
<span class="source-line-no">1155</span><span id="line-1155"> public IsFlushWALMarker(FlushAction... actions) {</span>
<span class="source-line-no">1156</span><span id="line-1156"> this.actions = actions;</span>
<span class="source-line-no">1157</span><span id="line-1157"> }</span>
<span class="source-line-no">1158</span><span id="line-1158"></span>
<span class="source-line-no">1159</span><span id="line-1159"> @Override</span>
<span class="source-line-no">1160</span><span id="line-1160"> public boolean matches(WALEdit edit) {</span>
<span class="source-line-no">1161</span><span id="line-1161"> List&lt;Cell&gt; cells = edit.getCells();</span>
<span class="source-line-no">1162</span><span id="line-1162"> if (cells.isEmpty()) {</span>
<span class="source-line-no">1163</span><span id="line-1163"> return false;</span>
<span class="source-line-no">1164</span><span id="line-1164"> }</span>
<span class="source-line-no">1165</span><span id="line-1165"> if (WALEdit.isMetaEditFamily(cells.get(0))) {</span>
<span class="source-line-no">1166</span><span id="line-1166"> FlushDescriptor desc;</span>
<span class="source-line-no">1167</span><span id="line-1167"> try {</span>
<span class="source-line-no">1168</span><span id="line-1168"> desc = WALEdit.getFlushDescriptor(cells.get(0));</span>
<span class="source-line-no">1169</span><span id="line-1169"> } catch (IOException e) {</span>
<span class="source-line-no">1170</span><span id="line-1170"> LOG.warn(e.toString(), e);</span>
<span class="source-line-no">1171</span><span id="line-1171"> return false;</span>
<span class="source-line-no">1172</span><span id="line-1172"> }</span>
<span class="source-line-no">1173</span><span id="line-1173"> if (desc != null) {</span>
<span class="source-line-no">1174</span><span id="line-1174"> for (FlushAction action : actions) {</span>
<span class="source-line-no">1175</span><span id="line-1175"> if (desc.getAction() == action) {</span>
<span class="source-line-no">1176</span><span id="line-1176"> return true;</span>
<span class="source-line-no">1177</span><span id="line-1177"> }</span>
<span class="source-line-no">1178</span><span id="line-1178"> }</span>
<span class="source-line-no">1179</span><span id="line-1179"> }</span>
<span class="source-line-no">1180</span><span id="line-1180"> }</span>
<span class="source-line-no">1181</span><span id="line-1181"> return false;</span>
<span class="source-line-no">1182</span><span id="line-1182"> }</span>
<span class="source-line-no">1183</span><span id="line-1183"></span>
<span class="source-line-no">1184</span><span id="line-1184"> public IsFlushWALMarker set(FlushAction... actions) {</span>
<span class="source-line-no">1185</span><span id="line-1185"> this.actions = actions;</span>
<span class="source-line-no">1186</span><span id="line-1186"> return this;</span>
<span class="source-line-no">1187</span><span id="line-1187"> }</span>
<span class="source-line-no">1188</span><span id="line-1188"> }</span>
<span class="source-line-no">1189</span><span id="line-1189"></span>
<span class="source-line-no">1190</span><span id="line-1190"> @Test</span>
<span class="source-line-no">1191</span><span id="line-1191"> public void testFlushMarkersWALFail() throws Exception {</span>
<span class="source-line-no">1192</span><span id="line-1192"> // test the cases where the WAL append for flush markers fail.</span>
<span class="source-line-no">1193</span><span id="line-1193"> byte[] family = Bytes.toBytes("family");</span>
<span class="source-line-no">1194</span><span id="line-1194"></span>
<span class="source-line-no">1195</span><span id="line-1195"> // spy an actual WAL implementation to throw exception (was not able to mock)</span>
<span class="source-line-no">1196</span><span id="line-1196"> Path logDir = TEST_UTIL.getDataTestDirOnTestFS(method + "log");</span>
<span class="source-line-no">1197</span><span id="line-1197"></span>
<span class="source-line-no">1198</span><span id="line-1198"> final Configuration walConf = new Configuration(TEST_UTIL.getConfiguration());</span>
<span class="source-line-no">1199</span><span id="line-1199"> CommonFSUtils.setRootDir(walConf, logDir);</span>
<span class="source-line-no">1200</span><span id="line-1200"> // Make up a WAL that we can manipulate at append time.</span>
<span class="source-line-no">1201</span><span id="line-1201"> class FailAppendFlushMarkerWAL extends FSHLog {</span>
<span class="source-line-no">1202</span><span id="line-1202"> volatile FlushAction[] flushActions = null;</span>
<span class="source-line-no">1203</span><span id="line-1203"></span>
<span class="source-line-no">1204</span><span id="line-1204"> public FailAppendFlushMarkerWAL(FileSystem fs, Path root, String logDir, Configuration conf)</span>
<span class="source-line-no">1205</span><span id="line-1205"> throws IOException {</span>
<span class="source-line-no">1206</span><span id="line-1206"> super(fs, root, logDir, conf);</span>
<span class="source-line-no">1207</span><span id="line-1207"> }</span>
<span class="source-line-no">1208</span><span id="line-1208"></span>
<span class="source-line-no">1209</span><span id="line-1209"> @Override</span>
<span class="source-line-no">1210</span><span id="line-1210"> protected Writer createWriterInstance(FileSystem fs, Path path) throws IOException {</span>
<span class="source-line-no">1211</span><span id="line-1211"> final Writer w = super.createWriterInstance(fs, path);</span>
<span class="source-line-no">1212</span><span id="line-1212"> return new Writer() {</span>
<span class="source-line-no">1213</span><span id="line-1213"> @Override</span>
<span class="source-line-no">1214</span><span id="line-1214"> public void close() throws IOException {</span>
<span class="source-line-no">1215</span><span id="line-1215"> w.close();</span>
<span class="source-line-no">1216</span><span id="line-1216"> }</span>
<span class="source-line-no">1217</span><span id="line-1217"></span>
<span class="source-line-no">1218</span><span id="line-1218"> @Override</span>
<span class="source-line-no">1219</span><span id="line-1219"> public void sync(boolean forceSync) throws IOException {</span>
<span class="source-line-no">1220</span><span id="line-1220"> w.sync(forceSync);</span>
<span class="source-line-no">1221</span><span id="line-1221"> }</span>
<span class="source-line-no">1222</span><span id="line-1222"></span>
<span class="source-line-no">1223</span><span id="line-1223"> @Override</span>
<span class="source-line-no">1224</span><span id="line-1224"> public void append(Entry entry) throws IOException {</span>
<span class="source-line-no">1225</span><span id="line-1225"> List&lt;Cell&gt; cells = entry.getEdit().getCells();</span>
<span class="source-line-no">1226</span><span id="line-1226"> if (WALEdit.isMetaEditFamily(cells.get(0))) {</span>
<span class="source-line-no">1227</span><span id="line-1227"> FlushDescriptor desc = WALEdit.getFlushDescriptor(cells.get(0));</span>
<span class="source-line-no">1228</span><span id="line-1228"> if (desc != null) {</span>
<span class="source-line-no">1229</span><span id="line-1229"> for (FlushAction flushAction : flushActions) {</span>
<span class="source-line-no">1230</span><span id="line-1230"> if (desc.getAction().equals(flushAction)) {</span>
<span class="source-line-no">1231</span><span id="line-1231"> throw new IOException("Failed to append flush marker! " + flushAction);</span>
<span class="source-line-no">1232</span><span id="line-1232"> }</span>
<span class="source-line-no">1233</span><span id="line-1233"> }</span>
<span class="source-line-no">1234</span><span id="line-1234"> }</span>
<span class="source-line-no">1235</span><span id="line-1235"> }</span>
<span class="source-line-no">1236</span><span id="line-1236"> w.append(entry);</span>
<span class="source-line-no">1237</span><span id="line-1237"> }</span>
<span class="source-line-no">1238</span><span id="line-1238"></span>
<span class="source-line-no">1239</span><span id="line-1239"> @Override</span>
<span class="source-line-no">1240</span><span id="line-1240"> public long getLength() {</span>
<span class="source-line-no">1241</span><span id="line-1241"> return w.getLength();</span>
<span class="source-line-no">1242</span><span id="line-1242"> }</span>
<span class="source-line-no">1243</span><span id="line-1243"></span>
<span class="source-line-no">1244</span><span id="line-1244"> @Override</span>
<span class="source-line-no">1245</span><span id="line-1245"> public long getSyncedLength() {</span>
<span class="source-line-no">1246</span><span id="line-1246"> return w.getSyncedLength();</span>
<span class="source-line-no">1247</span><span id="line-1247"> }</span>
<span class="source-line-no">1248</span><span id="line-1248"> };</span>
<span class="source-line-no">1249</span><span id="line-1249"> }</span>
<span class="source-line-no">1250</span><span id="line-1250"> }</span>
<span class="source-line-no">1251</span><span id="line-1251"> FailAppendFlushMarkerWAL wal = new FailAppendFlushMarkerWAL(FileSystem.get(walConf),</span>
<span class="source-line-no">1252</span><span id="line-1252"> CommonFSUtils.getRootDir(walConf), method, walConf);</span>
<span class="source-line-no">1253</span><span id="line-1253"> wal.init();</span>
<span class="source-line-no">1254</span><span id="line-1254"> this.region = initHRegion(tableName, HConstants.EMPTY_START_ROW, HConstants.EMPTY_END_ROW, CONF,</span>
<span class="source-line-no">1255</span><span id="line-1255"> false, Durability.USE_DEFAULT, wal, family);</span>
<span class="source-line-no">1256</span><span id="line-1256"> int i = 0;</span>
<span class="source-line-no">1257</span><span id="line-1257"> Put put = new Put(Bytes.toBytes(i));</span>
<span class="source-line-no">1258</span><span id="line-1258"> put.setDurability(Durability.SKIP_WAL); // have to skip mocked wal</span>
<span class="source-line-no">1259</span><span id="line-1259"> put.addColumn(family, Bytes.toBytes(i), Bytes.toBytes(i));</span>
<span class="source-line-no">1260</span><span id="line-1260"> region.put(put);</span>
<span class="source-line-no">1261</span><span id="line-1261"></span>
<span class="source-line-no">1262</span><span id="line-1262"> // 1. Test case where START_FLUSH throws exception</span>
<span class="source-line-no">1263</span><span id="line-1263"> wal.flushActions = new FlushAction[] { FlushAction.START_FLUSH };</span>
<span class="source-line-no">1264</span><span id="line-1264"></span>
<span class="source-line-no">1265</span><span id="line-1265"> // start cache flush will throw exception</span>
<span class="source-line-no">1266</span><span id="line-1266"> try {</span>
<span class="source-line-no">1267</span><span id="line-1267"> region.flush(true);</span>
<span class="source-line-no">1268</span><span id="line-1268"> fail("This should have thrown exception");</span>
<span class="source-line-no">1269</span><span id="line-1269"> } catch (DroppedSnapshotException unexpected) {</span>
<span class="source-line-no">1270</span><span id="line-1270"> // this should not be a dropped snapshot exception. Meaning that RS will not abort</span>
<span class="source-line-no">1271</span><span id="line-1271"> throw unexpected;</span>
<span class="source-line-no">1272</span><span id="line-1272"> } catch (IOException expected) {</span>
<span class="source-line-no">1273</span><span id="line-1273"> // expected</span>
<span class="source-line-no">1274</span><span id="line-1274"> }</span>
<span class="source-line-no">1275</span><span id="line-1275"> // The WAL is hosed now. It has two edits appended. We cannot roll the log without it</span>
<span class="source-line-no">1276</span><span id="line-1276"> // throwing a DroppedSnapshotException to force an abort. Just clean up the mess.</span>
<span class="source-line-no">1277</span><span id="line-1277"> region.close(true);</span>
<span class="source-line-no">1278</span><span id="line-1278"> wal.close();</span>
<span class="source-line-no">1279</span><span id="line-1279"> // release the snapshot and active segment, so netty will not report memory leak</span>
<span class="source-line-no">1280</span><span id="line-1280"> for (HStore store : region.getStores()) {</span>
<span class="source-line-no">1281</span><span id="line-1281"> AbstractMemStore memstore = (AbstractMemStore) store.memstore;</span>
<span class="source-line-no">1282</span><span id="line-1282"> memstore.doClearSnapShot();</span>
<span class="source-line-no">1283</span><span id="line-1283"> memstore.close();</span>
<span class="source-line-no">1284</span><span id="line-1284"> }</span>
<span class="source-line-no">1285</span><span id="line-1285"></span>
<span class="source-line-no">1286</span><span id="line-1286"> // 2. Test case where START_FLUSH succeeds but COMMIT_FLUSH will throw exception</span>
<span class="source-line-no">1287</span><span id="line-1287"> wal.flushActions = new FlushAction[] { FlushAction.COMMIT_FLUSH };</span>
<span class="source-line-no">1288</span><span id="line-1288"> wal = new FailAppendFlushMarkerWAL(FileSystem.get(walConf), CommonFSUtils.getRootDir(walConf),</span>
<span class="source-line-no">1289</span><span id="line-1289"> method, walConf);</span>
<span class="source-line-no">1290</span><span id="line-1290"> wal.init();</span>
<span class="source-line-no">1291</span><span id="line-1291"> this.region = initHRegion(tableName, HConstants.EMPTY_START_ROW, HConstants.EMPTY_END_ROW, CONF,</span>
<span class="source-line-no">1292</span><span id="line-1292"> false, Durability.USE_DEFAULT, wal, family);</span>
<span class="source-line-no">1293</span><span id="line-1293"> region.put(put);</span>
<span class="source-line-no">1294</span><span id="line-1294"> // 3. Test case where ABORT_FLUSH will throw exception.</span>
<span class="source-line-no">1295</span><span id="line-1295"> // Even if ABORT_FLUSH throws exception, we should not fail with IOE, but continue with</span>
<span class="source-line-no">1296</span><span id="line-1296"> // DroppedSnapshotException. Below COMMIT_FLUSH will cause flush to abort</span>
<span class="source-line-no">1297</span><span id="line-1297"> wal.flushActions = new FlushAction[] { FlushAction.COMMIT_FLUSH, FlushAction.ABORT_FLUSH };</span>
<span class="source-line-no">1298</span><span id="line-1298"></span>
<span class="source-line-no">1299</span><span id="line-1299"> // we expect this exception, since we were able to write the snapshot, but failed to</span>
<span class="source-line-no">1300</span><span id="line-1300"> // write the flush marker to WAL</span>
<span class="source-line-no">1301</span><span id="line-1301"> assertThrows(DroppedSnapshotException.class, () -&gt; region.flush(true));</span>
<span class="source-line-no">1302</span><span id="line-1302"></span>
<span class="source-line-no">1303</span><span id="line-1303"> region.close(true);</span>
<span class="source-line-no">1304</span><span id="line-1304"> // release the snapshot and active segment, so netty will not report memory leak</span>
<span class="source-line-no">1305</span><span id="line-1305"> for (HStore store : region.getStores()) {</span>
<span class="source-line-no">1306</span><span id="line-1306"> AbstractMemStore memstore = (AbstractMemStore) store.memstore;</span>
<span class="source-line-no">1307</span><span id="line-1307"> memstore.doClearSnapShot();</span>
<span class="source-line-no">1308</span><span id="line-1308"> memstore.close();</span>
<span class="source-line-no">1309</span><span id="line-1309"> }</span>
<span class="source-line-no">1310</span><span id="line-1310"> region = null;</span>
<span class="source-line-no">1311</span><span id="line-1311"> }</span>
<span class="source-line-no">1312</span><span id="line-1312"></span>
<span class="source-line-no">1313</span><span id="line-1313"> @Test</span>
<span class="source-line-no">1314</span><span id="line-1314"> public void testGetWhileRegionClose() throws IOException {</span>
<span class="source-line-no">1315</span><span id="line-1315"> Configuration hc = initSplit();</span>
<span class="source-line-no">1316</span><span id="line-1316"> int numRows = 100;</span>
<span class="source-line-no">1317</span><span id="line-1317"> byte[][] families = { fam1, fam2, fam3 };</span>
<span class="source-line-no">1318</span><span id="line-1318"></span>
<span class="source-line-no">1319</span><span id="line-1319"> // Setting up region</span>
<span class="source-line-no">1320</span><span id="line-1320"> this.region = initHRegion(tableName, method, hc, families);</span>
<span class="source-line-no">1321</span><span id="line-1321"> // Put data in region</span>
<span class="source-line-no">1322</span><span id="line-1322"> final int startRow = 100;</span>
<span class="source-line-no">1323</span><span id="line-1323"> putData(startRow, numRows, qual1, families);</span>
<span class="source-line-no">1324</span><span id="line-1324"> putData(startRow, numRows, qual2, families);</span>
<span class="source-line-no">1325</span><span id="line-1325"> putData(startRow, numRows, qual3, families);</span>
<span class="source-line-no">1326</span><span id="line-1326"> final AtomicBoolean done = new AtomicBoolean(false);</span>
<span class="source-line-no">1327</span><span id="line-1327"> final AtomicInteger gets = new AtomicInteger(0);</span>
<span class="source-line-no">1328</span><span id="line-1328"> GetTillDoneOrException[] threads = new GetTillDoneOrException[10];</span>
<span class="source-line-no">1329</span><span id="line-1329"> try {</span>
<span class="source-line-no">1330</span><span id="line-1330"> // Set ten threads running concurrently getting from the region.</span>
<span class="source-line-no">1331</span><span id="line-1331"> for (int i = 0; i &lt; threads.length / 2; i++) {</span>
<span class="source-line-no">1332</span><span id="line-1332"> threads[i] = new GetTillDoneOrException(i, Bytes.toBytes("" + startRow), done, gets);</span>
<span class="source-line-no">1333</span><span id="line-1333"> threads[i].setDaemon(true);</span>
<span class="source-line-no">1334</span><span id="line-1334"> threads[i].start();</span>
<span class="source-line-no">1335</span><span id="line-1335"> }</span>
<span class="source-line-no">1336</span><span id="line-1336"> // Artificially make the condition by setting closing flag explicitly.</span>
<span class="source-line-no">1337</span><span id="line-1337"> // I can't make the issue happen with a call to region.close().</span>
<span class="source-line-no">1338</span><span id="line-1338"> this.region.closing.set(true);</span>
<span class="source-line-no">1339</span><span id="line-1339"> for (int i = threads.length / 2; i &lt; threads.length; i++) {</span>
<span class="source-line-no">1340</span><span id="line-1340"> threads[i] = new GetTillDoneOrException(i, Bytes.toBytes("" + startRow), done, gets);</span>
<span class="source-line-no">1341</span><span id="line-1341"> threads[i].setDaemon(true);</span>
<span class="source-line-no">1342</span><span id="line-1342"> threads[i].start();</span>
<span class="source-line-no">1343</span><span id="line-1343"> }</span>
<span class="source-line-no">1344</span><span id="line-1344"> } finally {</span>
<span class="source-line-no">1345</span><span id="line-1345"> if (this.region != null) {</span>
<span class="source-line-no">1346</span><span id="line-1346"> HBaseTestingUtil.closeRegionAndWAL(this.region);</span>
<span class="source-line-no">1347</span><span id="line-1347"> this.region = null;</span>
<span class="source-line-no">1348</span><span id="line-1348"> }</span>
<span class="source-line-no">1349</span><span id="line-1349"> }</span>
<span class="source-line-no">1350</span><span id="line-1350"> done.set(true);</span>
<span class="source-line-no">1351</span><span id="line-1351"> for (GetTillDoneOrException t : threads) {</span>
<span class="source-line-no">1352</span><span id="line-1352"> try {</span>
<span class="source-line-no">1353</span><span id="line-1353"> t.join();</span>
<span class="source-line-no">1354</span><span id="line-1354"> } catch (InterruptedException e) {</span>
<span class="source-line-no">1355</span><span id="line-1355"> e.printStackTrace();</span>
<span class="source-line-no">1356</span><span id="line-1356"> }</span>
<span class="source-line-no">1357</span><span id="line-1357"> if (t.e != null) {</span>
<span class="source-line-no">1358</span><span id="line-1358"> LOG.info("Exception=" + t.e);</span>
<span class="source-line-no">1359</span><span id="line-1359"> assertFalse("Found a NPE in " + t.getName(), t.e instanceof NullPointerException);</span>
<span class="source-line-no">1360</span><span id="line-1360"> }</span>
<span class="source-line-no">1361</span><span id="line-1361"> }</span>
<span class="source-line-no">1362</span><span id="line-1362"> }</span>
<span class="source-line-no">1363</span><span id="line-1363"></span>
<span class="source-line-no">1364</span><span id="line-1364"> /*</span>
<span class="source-line-no">1365</span><span id="line-1365"> * Thread that does get on single row until 'done' flag is flipped. If an exception causes us to</span>
<span class="source-line-no">1366</span><span id="line-1366"> * fail, it records it.</span>
<span class="source-line-no">1367</span><span id="line-1367"> */</span>
<span class="source-line-no">1368</span><span id="line-1368"> class GetTillDoneOrException extends Thread {</span>
<span class="source-line-no">1369</span><span id="line-1369"> private final Get g;</span>
<span class="source-line-no">1370</span><span id="line-1370"> private final AtomicBoolean done;</span>
<span class="source-line-no">1371</span><span id="line-1371"> private final AtomicInteger count;</span>
<span class="source-line-no">1372</span><span id="line-1372"> private Exception e;</span>
<span class="source-line-no">1373</span><span id="line-1373"></span>
<span class="source-line-no">1374</span><span id="line-1374"> GetTillDoneOrException(final int i, final byte[] r, final AtomicBoolean d,</span>
<span class="source-line-no">1375</span><span id="line-1375"> final AtomicInteger c) {</span>
<span class="source-line-no">1376</span><span id="line-1376"> super("getter." + i);</span>
<span class="source-line-no">1377</span><span id="line-1377"> this.g = new Get(r);</span>
<span class="source-line-no">1378</span><span id="line-1378"> this.done = d;</span>
<span class="source-line-no">1379</span><span id="line-1379"> this.count = c;</span>
<span class="source-line-no">1380</span><span id="line-1380"> }</span>
<span class="source-line-no">1381</span><span id="line-1381"></span>
<span class="source-line-no">1382</span><span id="line-1382"> @Override</span>
<span class="source-line-no">1383</span><span id="line-1383"> public void run() {</span>
<span class="source-line-no">1384</span><span id="line-1384"> while (!this.done.get()) {</span>
<span class="source-line-no">1385</span><span id="line-1385"> try {</span>
<span class="source-line-no">1386</span><span id="line-1386"> assertTrue(region.get(g).size() &gt; 0);</span>
<span class="source-line-no">1387</span><span id="line-1387"> this.count.incrementAndGet();</span>
<span class="source-line-no">1388</span><span id="line-1388"> } catch (Exception e) {</span>
<span class="source-line-no">1389</span><span id="line-1389"> this.e = e;</span>
<span class="source-line-no">1390</span><span id="line-1390"> break;</span>
<span class="source-line-no">1391</span><span id="line-1391"> }</span>
<span class="source-line-no">1392</span><span id="line-1392"> }</span>
<span class="source-line-no">1393</span><span id="line-1393"> }</span>
<span class="source-line-no">1394</span><span id="line-1394"> }</span>
<span class="source-line-no">1395</span><span id="line-1395"></span>
<span class="source-line-no">1396</span><span id="line-1396"> /*</span>
<span class="source-line-no">1397</span><span id="line-1397"> * An involved filter test. Has multiple column families and deletes in mix.</span>
<span class="source-line-no">1398</span><span id="line-1398"> */</span>
<span class="source-line-no">1399</span><span id="line-1399"> @Test</span>
<span class="source-line-no">1400</span><span id="line-1400"> public void testWeirdCacheBehaviour() throws Exception {</span>
<span class="source-line-no">1401</span><span id="line-1401"> final TableName tableName = TableName.valueOf(name.getMethodName());</span>
<span class="source-line-no">1402</span><span id="line-1402"> byte[][] FAMILIES = new byte[][] { Bytes.toBytes("trans-blob"), Bytes.toBytes("trans-type"),</span>
<span class="source-line-no">1403</span><span id="line-1403"> Bytes.toBytes("trans-date"), Bytes.toBytes("trans-tags"), Bytes.toBytes("trans-group") };</span>
<span class="source-line-no">1404</span><span id="line-1404"> this.region = initHRegion(tableName, method, CONF, FAMILIES);</span>
<span class="source-line-no">1405</span><span id="line-1405"> String value = "this is the value";</span>
<span class="source-line-no">1406</span><span id="line-1406"> String value2 = "this is some other value";</span>
<span class="source-line-no">1407</span><span id="line-1407"> String keyPrefix1 = "prefix1";</span>
<span class="source-line-no">1408</span><span id="line-1408"> String keyPrefix2 = "prefix2";</span>
<span class="source-line-no">1409</span><span id="line-1409"> String keyPrefix3 = "prefix3";</span>
<span class="source-line-no">1410</span><span id="line-1410"> putRows(this.region, 3, value, keyPrefix1);</span>
<span class="source-line-no">1411</span><span id="line-1411"> putRows(this.region, 3, value, keyPrefix2);</span>
<span class="source-line-no">1412</span><span id="line-1412"> putRows(this.region, 3, value, keyPrefix3);</span>
<span class="source-line-no">1413</span><span id="line-1413"> putRows(this.region, 3, value2, keyPrefix1);</span>
<span class="source-line-no">1414</span><span id="line-1414"> putRows(this.region, 3, value2, keyPrefix2);</span>
<span class="source-line-no">1415</span><span id="line-1415"> putRows(this.region, 3, value2, keyPrefix3);</span>
<span class="source-line-no">1416</span><span id="line-1416"> System.out.println("Checking values for key: " + keyPrefix1);</span>
<span class="source-line-no">1417</span><span id="line-1417"> assertEquals("Got back incorrect number of rows from scan", 3,</span>
<span class="source-line-no">1418</span><span id="line-1418"> getNumberOfRows(keyPrefix1, value2, this.region));</span>
<span class="source-line-no">1419</span><span id="line-1419"> System.out.println("Checking values for key: " + keyPrefix2);</span>
<span class="source-line-no">1420</span><span id="line-1420"> assertEquals("Got back incorrect number of rows from scan", 3,</span>
<span class="source-line-no">1421</span><span id="line-1421"> getNumberOfRows(keyPrefix2, value2, this.region));</span>
<span class="source-line-no">1422</span><span id="line-1422"> System.out.println("Checking values for key: " + keyPrefix3);</span>
<span class="source-line-no">1423</span><span id="line-1423"> assertEquals("Got back incorrect number of rows from scan", 3,</span>
<span class="source-line-no">1424</span><span id="line-1424"> getNumberOfRows(keyPrefix3, value2, this.region));</span>
<span class="source-line-no">1425</span><span id="line-1425"> deleteColumns(this.region, value2, keyPrefix1);</span>
<span class="source-line-no">1426</span><span id="line-1426"> deleteColumns(this.region, value2, keyPrefix2);</span>
<span class="source-line-no">1427</span><span id="line-1427"> deleteColumns(this.region, value2, keyPrefix3);</span>
<span class="source-line-no">1428</span><span id="line-1428"> System.out.println("Starting important checks.....");</span>
<span class="source-line-no">1429</span><span id="line-1429"> assertEquals("Got back incorrect number of rows from scan: " + keyPrefix1, 0,</span>
<span class="source-line-no">1430</span><span id="line-1430"> getNumberOfRows(keyPrefix1, value2, this.region));</span>
<span class="source-line-no">1431</span><span id="line-1431"> assertEquals("Got back incorrect number of rows from scan: " + keyPrefix2, 0,</span>
<span class="source-line-no">1432</span><span id="line-1432"> getNumberOfRows(keyPrefix2, value2, this.region));</span>
<span class="source-line-no">1433</span><span id="line-1433"> assertEquals("Got back incorrect number of rows from scan: " + keyPrefix3, 0,</span>
<span class="source-line-no">1434</span><span id="line-1434"> getNumberOfRows(keyPrefix3, value2, this.region));</span>
<span class="source-line-no">1435</span><span id="line-1435"> }</span>
<span class="source-line-no">1436</span><span id="line-1436"></span>
<span class="source-line-no">1437</span><span id="line-1437"> @Test</span>
<span class="source-line-no">1438</span><span id="line-1438"> public void testAppendWithReadOnlyTable() throws Exception {</span>
<span class="source-line-no">1439</span><span id="line-1439"> final TableName tableName = TableName.valueOf(name.getMethodName());</span>
<span class="source-line-no">1440</span><span id="line-1440"> this.region = initHRegion(tableName, method, CONF, true, Bytes.toBytes("somefamily"));</span>
<span class="source-line-no">1441</span><span id="line-1441"> boolean exceptionCaught = false;</span>
<span class="source-line-no">1442</span><span id="line-1442"> Append append = new Append(Bytes.toBytes("somerow"));</span>
<span class="source-line-no">1443</span><span id="line-1443"> append.setDurability(Durability.SKIP_WAL);</span>
<span class="source-line-no">1444</span><span id="line-1444"> append.addColumn(Bytes.toBytes("somefamily"), Bytes.toBytes("somequalifier"),</span>
<span class="source-line-no">1445</span><span id="line-1445"> Bytes.toBytes("somevalue"));</span>
<span class="source-line-no">1446</span><span id="line-1446"> try {</span>
<span class="source-line-no">1447</span><span id="line-1447"> region.append(append);</span>
<span class="source-line-no">1448</span><span id="line-1448"> } catch (IOException e) {</span>
<span class="source-line-no">1449</span><span id="line-1449"> exceptionCaught = true;</span>
<span class="source-line-no">1450</span><span id="line-1450"> }</span>
<span class="source-line-no">1451</span><span id="line-1451"> assertTrue(exceptionCaught == true);</span>
<span class="source-line-no">1452</span><span id="line-1452"> }</span>
<span class="source-line-no">1453</span><span id="line-1453"></span>
<span class="source-line-no">1454</span><span id="line-1454"> @Test</span>
<span class="source-line-no">1455</span><span id="line-1455"> public void testIncrWithReadOnlyTable() throws Exception {</span>
<span class="source-line-no">1456</span><span id="line-1456"> final TableName tableName = TableName.valueOf(name.getMethodName());</span>
<span class="source-line-no">1457</span><span id="line-1457"> this.region = initHRegion(tableName, method, CONF, true, Bytes.toBytes("somefamily"));</span>
<span class="source-line-no">1458</span><span id="line-1458"> boolean exceptionCaught = false;</span>
<span class="source-line-no">1459</span><span id="line-1459"> Increment inc = new Increment(Bytes.toBytes("somerow"));</span>
<span class="source-line-no">1460</span><span id="line-1460"> inc.setDurability(Durability.SKIP_WAL);</span>
<span class="source-line-no">1461</span><span id="line-1461"> inc.addColumn(Bytes.toBytes("somefamily"), Bytes.toBytes("somequalifier"), 1L);</span>
<span class="source-line-no">1462</span><span id="line-1462"> try {</span>
<span class="source-line-no">1463</span><span id="line-1463"> region.increment(inc);</span>
<span class="source-line-no">1464</span><span id="line-1464"> } catch (IOException e) {</span>
<span class="source-line-no">1465</span><span id="line-1465"> exceptionCaught = true;</span>
<span class="source-line-no">1466</span><span id="line-1466"> }</span>
<span class="source-line-no">1467</span><span id="line-1467"> assertTrue(exceptionCaught == true);</span>
<span class="source-line-no">1468</span><span id="line-1468"> }</span>
<span class="source-line-no">1469</span><span id="line-1469"></span>
<span class="source-line-no">1470</span><span id="line-1470"> private void deleteColumns(HRegion r, String value, String keyPrefix) throws IOException {</span>
<span class="source-line-no">1471</span><span id="line-1471"> int count = 0;</span>
<span class="source-line-no">1472</span><span id="line-1472"> try (InternalScanner scanner = buildScanner(keyPrefix, value, r)) {</span>
<span class="source-line-no">1473</span><span id="line-1473"> boolean more = false;</span>
<span class="source-line-no">1474</span><span id="line-1474"> List&lt;Cell&gt; results = new ArrayList&lt;&gt;();</span>
<span class="source-line-no">1475</span><span id="line-1475"> do {</span>
<span class="source-line-no">1476</span><span id="line-1476"> more = scanner.next(results);</span>
<span class="source-line-no">1477</span><span id="line-1477"> if (results != null &amp;&amp; !results.isEmpty()) {</span>
<span class="source-line-no">1478</span><span id="line-1478"> count++;</span>
<span class="source-line-no">1479</span><span id="line-1479"> } else {</span>
<span class="source-line-no">1480</span><span id="line-1480"> break;</span>
<span class="source-line-no">1481</span><span id="line-1481"> }</span>
<span class="source-line-no">1482</span><span id="line-1482"> Delete delete = new Delete(CellUtil.cloneRow(results.get(0)));</span>
<span class="source-line-no">1483</span><span id="line-1483"> delete.addColumn(Bytes.toBytes("trans-tags"), Bytes.toBytes("qual2"));</span>
<span class="source-line-no">1484</span><span id="line-1484"> r.delete(delete);</span>
<span class="source-line-no">1485</span><span id="line-1485"> results.clear();</span>
<span class="source-line-no">1486</span><span id="line-1486"> } while (more);</span>
<span class="source-line-no">1487</span><span id="line-1487"> }</span>
<span class="source-line-no">1488</span><span id="line-1488"> assertEquals("Did not perform correct number of deletes", 3, count);</span>
<span class="source-line-no">1489</span><span id="line-1489"> }</span>
<span class="source-line-no">1490</span><span id="line-1490"></span>
<span class="source-line-no">1491</span><span id="line-1491"> private int getNumberOfRows(String keyPrefix, String value, HRegion r) throws Exception {</span>
<span class="source-line-no">1492</span><span id="line-1492"> try (InternalScanner resultScanner = buildScanner(keyPrefix, value, r)) {</span>
<span class="source-line-no">1493</span><span id="line-1493"> int numberOfResults = 0;</span>
<span class="source-line-no">1494</span><span id="line-1494"> List&lt;Cell&gt; results = new ArrayList&lt;&gt;();</span>
<span class="source-line-no">1495</span><span id="line-1495"> boolean more = false;</span>
<span class="source-line-no">1496</span><span id="line-1496"> do {</span>
<span class="source-line-no">1497</span><span id="line-1497"> more = resultScanner.next(results);</span>
<span class="source-line-no">1498</span><span id="line-1498"> if (results != null &amp;&amp; !results.isEmpty()) {</span>
<span class="source-line-no">1499</span><span id="line-1499"> numberOfResults++;</span>
<span class="source-line-no">1500</span><span id="line-1500"> } else {</span>
<span class="source-line-no">1501</span><span id="line-1501"> break;</span>
<span class="source-line-no">1502</span><span id="line-1502"> }</span>
<span class="source-line-no">1503</span><span id="line-1503"> for (Cell kv : results) {</span>
<span class="source-line-no">1504</span><span id="line-1504"> LOG.info("kv=" + kv.toString() + ", " + Bytes.toString(CellUtil.cloneValue(kv)));</span>
<span class="source-line-no">1505</span><span id="line-1505"> }</span>
<span class="source-line-no">1506</span><span id="line-1506"> results.clear();</span>
<span class="source-line-no">1507</span><span id="line-1507"> } while (more);</span>
<span class="source-line-no">1508</span><span id="line-1508"> return numberOfResults;</span>
<span class="source-line-no">1509</span><span id="line-1509"> }</span>
<span class="source-line-no">1510</span><span id="line-1510"> }</span>
<span class="source-line-no">1511</span><span id="line-1511"></span>
<span class="source-line-no">1512</span><span id="line-1512"> private InternalScanner buildScanner(String keyPrefix, String value, HRegion r)</span>
<span class="source-line-no">1513</span><span id="line-1513"> throws IOException {</span>
<span class="source-line-no">1514</span><span id="line-1514"> // Defaults FilterList.Operator.MUST_PASS_ALL.</span>
<span class="source-line-no">1515</span><span id="line-1515"> FilterList allFilters = new FilterList();</span>
<span class="source-line-no">1516</span><span id="line-1516"> allFilters.addFilter(new PrefixFilter(Bytes.toBytes(keyPrefix)));</span>
<span class="source-line-no">1517</span><span id="line-1517"> // Only return rows where this column value exists in the row.</span>
<span class="source-line-no">1518</span><span id="line-1518"> SingleColumnValueFilter filter = new SingleColumnValueFilter(Bytes.toBytes("trans-tags"),</span>
<span class="source-line-no">1519</span><span id="line-1519"> Bytes.toBytes("qual2"), CompareOperator.EQUAL, Bytes.toBytes(value));</span>
<span class="source-line-no">1520</span><span id="line-1520"> filter.setFilterIfMissing(true);</span>
<span class="source-line-no">1521</span><span id="line-1521"> allFilters.addFilter(filter);</span>
<span class="source-line-no">1522</span><span id="line-1522"> Scan scan = new Scan();</span>
<span class="source-line-no">1523</span><span id="line-1523"> scan.addFamily(Bytes.toBytes("trans-blob"));</span>
<span class="source-line-no">1524</span><span id="line-1524"> scan.addFamily(Bytes.toBytes("trans-type"));</span>
<span class="source-line-no">1525</span><span id="line-1525"> scan.addFamily(Bytes.toBytes("trans-date"));</span>
<span class="source-line-no">1526</span><span id="line-1526"> scan.addFamily(Bytes.toBytes("trans-tags"));</span>
<span class="source-line-no">1527</span><span id="line-1527"> scan.addFamily(Bytes.toBytes("trans-group"));</span>
<span class="source-line-no">1528</span><span id="line-1528"> scan.setFilter(allFilters);</span>
<span class="source-line-no">1529</span><span id="line-1529"> return r.getScanner(scan);</span>
<span class="source-line-no">1530</span><span id="line-1530"> }</span>
<span class="source-line-no">1531</span><span id="line-1531"></span>
<span class="source-line-no">1532</span><span id="line-1532"> private void putRows(HRegion r, int numRows, String value, String key) throws IOException {</span>
<span class="source-line-no">1533</span><span id="line-1533"> for (int i = 0; i &lt; numRows; i++) {</span>
<span class="source-line-no">1534</span><span id="line-1534"> String row = key + "_" + i/* UUID.randomUUID().toString() */;</span>
<span class="source-line-no">1535</span><span id="line-1535"> System.out.println(String.format("Saving row: %s, with value %s", row, value));</span>
<span class="source-line-no">1536</span><span id="line-1536"> Put put = new Put(Bytes.toBytes(row));</span>
<span class="source-line-no">1537</span><span id="line-1537"> put.setDurability(Durability.SKIP_WAL);</span>
<span class="source-line-no">1538</span><span id="line-1538"> put.addColumn(Bytes.toBytes("trans-blob"), null, Bytes.toBytes("value for blob"));</span>
<span class="source-line-no">1539</span><span id="line-1539"> put.addColumn(Bytes.toBytes("trans-type"), null, Bytes.toBytes("statement"));</span>
<span class="source-line-no">1540</span><span id="line-1540"> put.addColumn(Bytes.toBytes("trans-date"), null, Bytes.toBytes("20090921010101999"));</span>
<span class="source-line-no">1541</span><span id="line-1541"> put.addColumn(Bytes.toBytes("trans-tags"), Bytes.toBytes("qual2"), Bytes.toBytes(value));</span>
<span class="source-line-no">1542</span><span id="line-1542"> put.addColumn(Bytes.toBytes("trans-group"), null, Bytes.toBytes("adhocTransactionGroupId"));</span>
<span class="source-line-no">1543</span><span id="line-1543"> r.put(put);</span>
<span class="source-line-no">1544</span><span id="line-1544"> }</span>
<span class="source-line-no">1545</span><span id="line-1545"> }</span>
<span class="source-line-no">1546</span><span id="line-1546"></span>
<span class="source-line-no">1547</span><span id="line-1547"> @Test</span>
<span class="source-line-no">1548</span><span id="line-1548"> public void testFamilyWithAndWithoutColon() throws Exception {</span>
<span class="source-line-no">1549</span><span id="line-1549"> byte[] cf = Bytes.toBytes(COLUMN_FAMILY);</span>
<span class="source-line-no">1550</span><span id="line-1550"> this.region = initHRegion(tableName, method, CONF, cf);</span>
<span class="source-line-no">1551</span><span id="line-1551"> Put p = new Put(tableName.toBytes());</span>
<span class="source-line-no">1552</span><span id="line-1552"> byte[] cfwithcolon = Bytes.toBytes(COLUMN_FAMILY + ":");</span>
<span class="source-line-no">1553</span><span id="line-1553"> p.addColumn(cfwithcolon, cfwithcolon, cfwithcolon);</span>
<span class="source-line-no">1554</span><span id="line-1554"> boolean exception = false;</span>
<span class="source-line-no">1555</span><span id="line-1555"> try {</span>
<span class="source-line-no">1556</span><span id="line-1556"> this.region.put(p);</span>
<span class="source-line-no">1557</span><span id="line-1557"> } catch (NoSuchColumnFamilyException e) {</span>
<span class="source-line-no">1558</span><span id="line-1558"> exception = true;</span>
<span class="source-line-no">1559</span><span id="line-1559"> }</span>
<span class="source-line-no">1560</span><span id="line-1560"> assertTrue(exception);</span>
<span class="source-line-no">1561</span><span id="line-1561"> }</span>
<span class="source-line-no">1562</span><span id="line-1562"></span>
<span class="source-line-no">1563</span><span id="line-1563"> @Test</span>
<span class="source-line-no">1564</span><span id="line-1564"> public void testBatchPut_whileNoRowLocksHeld() throws IOException {</span>
<span class="source-line-no">1565</span><span id="line-1565"> final Put[] puts = new Put[10];</span>
<span class="source-line-no">1566</span><span id="line-1566"> MetricsWALSource source = CompatibilitySingletonFactory.getInstance(MetricsWALSource.class);</span>
<span class="source-line-no">1567</span><span id="line-1567"> long syncs = prepareRegionForBachPut(puts, source, false);</span>
<span class="source-line-no">1568</span><span id="line-1568"></span>
<span class="source-line-no">1569</span><span id="line-1569"> OperationStatus[] codes = this.region.batchMutate(puts);</span>
<span class="source-line-no">1570</span><span id="line-1570"> assertEquals(10, codes.length);</span>
<span class="source-line-no">1571</span><span id="line-1571"> for (int i = 0; i &lt; 10; i++) {</span>
<span class="source-line-no">1572</span><span id="line-1572"> assertEquals(OperationStatusCode.SUCCESS, codes[i].getOperationStatusCode());</span>
<span class="source-line-no">1573</span><span id="line-1573"> }</span>
<span class="source-line-no">1574</span><span id="line-1574"> metricsAssertHelper.assertCounter("syncTimeNumOps", syncs + 1, source);</span>
<span class="source-line-no">1575</span><span id="line-1575"></span>
<span class="source-line-no">1576</span><span id="line-1576"> LOG.info("Next a batch put with one invalid family");</span>
<span class="source-line-no">1577</span><span id="line-1577"> puts[5].addColumn(Bytes.toBytes("BAD_CF"), qual, value);</span>
<span class="source-line-no">1578</span><span id="line-1578"> codes = this.region.batchMutate(puts);</span>
<span class="source-line-no">1579</span><span id="line-1579"> assertEquals(10, codes.length);</span>
<span class="source-line-no">1580</span><span id="line-1580"> for (int i = 0; i &lt; 10; i++) {</span>
<span class="source-line-no">1581</span><span id="line-1581"> assertEquals((i == 5) ? OperationStatusCode.BAD_FAMILY : OperationStatusCode.SUCCESS,</span>
<span class="source-line-no">1582</span><span id="line-1582"> codes[i].getOperationStatusCode());</span>
<span class="source-line-no">1583</span><span id="line-1583"> }</span>
<span class="source-line-no">1584</span><span id="line-1584"></span>
<span class="source-line-no">1585</span><span id="line-1585"> metricsAssertHelper.assertCounter("syncTimeNumOps", syncs + 2, source);</span>
<span class="source-line-no">1586</span><span id="line-1586"> }</span>
<span class="source-line-no">1587</span><span id="line-1587"></span>
<span class="source-line-no">1588</span><span id="line-1588"> @Test</span>
<span class="source-line-no">1589</span><span id="line-1589"> public void testBatchPut_whileMultipleRowLocksHeld() throws Exception {</span>
<span class="source-line-no">1590</span><span id="line-1590"> final Put[] puts = new Put[10];</span>
<span class="source-line-no">1591</span><span id="line-1591"> MetricsWALSource source = CompatibilitySingletonFactory.getInstance(MetricsWALSource.class);</span>
<span class="source-line-no">1592</span><span id="line-1592"> long syncs = prepareRegionForBachPut(puts, source, false);</span>
<span class="source-line-no">1593</span><span id="line-1593"></span>
<span class="source-line-no">1594</span><span id="line-1594"> puts[5].addColumn(Bytes.toBytes("BAD_CF"), qual, value);</span>
<span class="source-line-no">1595</span><span id="line-1595"></span>
<span class="source-line-no">1596</span><span id="line-1596"> LOG.info("batchPut will have to break into four batches to avoid row locks");</span>
<span class="source-line-no">1597</span><span id="line-1597"> RowLock rowLock1 = region.getRowLock(Bytes.toBytes("row_2"));</span>
<span class="source-line-no">1598</span><span id="line-1598"> RowLock rowLock2 = region.getRowLock(Bytes.toBytes("row_1"));</span>
<span class="source-line-no">1599</span><span id="line-1599"> RowLock rowLock3 = region.getRowLock(Bytes.toBytes("row_3"));</span>
<span class="source-line-no">1600</span><span id="line-1600"> RowLock rowLock4 = region.getRowLock(Bytes.toBytes("row_3"), true);</span>
<span class="source-line-no">1601</span><span id="line-1601"></span>
<span class="source-line-no">1602</span><span id="line-1602"> MultithreadedTestUtil.TestContext ctx = new MultithreadedTestUtil.TestContext(CONF);</span>
<span class="source-line-no">1603</span><span id="line-1603"> final AtomicReference&lt;OperationStatus[]&gt; retFromThread = new AtomicReference&lt;&gt;();</span>
<span class="source-line-no">1604</span><span id="line-1604"> final CountDownLatch startingPuts = new CountDownLatch(1);</span>
<span class="source-line-no">1605</span><span id="line-1605"> final CountDownLatch startingClose = new CountDownLatch(1);</span>
<span class="source-line-no">1606</span><span id="line-1606"> TestThread putter = new TestThread(ctx) {</span>
<span class="source-line-no">1607</span><span id="line-1607"> @Override</span>
<span class="source-line-no">1608</span><span id="line-1608"> public void doWork() throws IOException {</span>
<span class="source-line-no">1609</span><span id="line-1609"> startingPuts.countDown();</span>
<span class="source-line-no">1610</span><span id="line-1610"> retFromThread.set(region.batchMutate(puts));</span>
<span class="source-line-no">1611</span><span id="line-1611"> }</span>
<span class="source-line-no">1612</span><span id="line-1612"> };</span>
<span class="source-line-no">1613</span><span id="line-1613"> LOG.info("...starting put thread while holding locks");</span>
<span class="source-line-no">1614</span><span id="line-1614"> ctx.addThread(putter);</span>
<span class="source-line-no">1615</span><span id="line-1615"> ctx.startThreads();</span>
<span class="source-line-no">1616</span><span id="line-1616"></span>
<span class="source-line-no">1617</span><span id="line-1617"> // Now attempt to close the region from another thread. Prior to HBASE-12565</span>
<span class="source-line-no">1618</span><span id="line-1618"> // this would cause the in-progress batchMutate operation to to fail with</span>
<span class="source-line-no">1619</span><span id="line-1619"> // exception because it use to release and re-acquire the close-guard lock</span>
<span class="source-line-no">1620</span><span id="line-1620"> // between batches. Caller then didn't get status indicating which writes succeeded.</span>
<span class="source-line-no">1621</span><span id="line-1621"> // We now expect this thread to block until the batchMutate call finishes.</span>
<span class="source-line-no">1622</span><span id="line-1622"> Thread regionCloseThread = new TestThread(ctx) {</span>
<span class="source-line-no">1623</span><span id="line-1623"> @Override</span>
<span class="source-line-no">1624</span><span id="line-1624"> public void doWork() {</span>
<span class="source-line-no">1625</span><span id="line-1625"> try {</span>
<span class="source-line-no">1626</span><span id="line-1626"> startingPuts.await();</span>
<span class="source-line-no">1627</span><span id="line-1627"> // Give some time for the batch mutate to get in.</span>
<span class="source-line-no">1628</span><span id="line-1628"> // We don't want to race with the mutate</span>
<span class="source-line-no">1629</span><span id="line-1629"> Thread.sleep(10);</span>
<span class="source-line-no">1630</span><span id="line-1630"> startingClose.countDown();</span>
<span class="source-line-no">1631</span><span id="line-1631"> HBaseTestingUtil.closeRegionAndWAL(region);</span>
<span class="source-line-no">1632</span><span id="line-1632"> region = null;</span>
<span class="source-line-no">1633</span><span id="line-1633"> } catch (IOException e) {</span>
<span class="source-line-no">1634</span><span id="line-1634"> throw new RuntimeException(e);</span>
<span class="source-line-no">1635</span><span id="line-1635"> } catch (InterruptedException e) {</span>
<span class="source-line-no">1636</span><span id="line-1636"> throw new RuntimeException(e);</span>
<span class="source-line-no">1637</span><span id="line-1637"> }</span>
<span class="source-line-no">1638</span><span id="line-1638"> }</span>
<span class="source-line-no">1639</span><span id="line-1639"> };</span>
<span class="source-line-no">1640</span><span id="line-1640"> regionCloseThread.start();</span>
<span class="source-line-no">1641</span><span id="line-1641"></span>
<span class="source-line-no">1642</span><span id="line-1642"> startingClose.await();</span>
<span class="source-line-no">1643</span><span id="line-1643"> startingPuts.await();</span>
<span class="source-line-no">1644</span><span id="line-1644"> Thread.sleep(100);</span>
<span class="source-line-no">1645</span><span id="line-1645"> LOG.info("...releasing row lock 1, which should let put thread continue");</span>
<span class="source-line-no">1646</span><span id="line-1646"> rowLock1.release();</span>
<span class="source-line-no">1647</span><span id="line-1647"> rowLock2.release();</span>
<span class="source-line-no">1648</span><span id="line-1648"> rowLock3.release();</span>
<span class="source-line-no">1649</span><span id="line-1649"> waitForCounter(source, "syncTimeNumOps", syncs + 1);</span>
<span class="source-line-no">1650</span><span id="line-1650"></span>
<span class="source-line-no">1651</span><span id="line-1651"> LOG.info("...joining on put thread");</span>
<span class="source-line-no">1652</span><span id="line-1652"> ctx.stop();</span>
<span class="source-line-no">1653</span><span id="line-1653"> regionCloseThread.join();</span>
<span class="source-line-no">1654</span><span id="line-1654"></span>
<span class="source-line-no">1655</span><span id="line-1655"> OperationStatus[] codes = retFromThread.get();</span>
<span class="source-line-no">1656</span><span id="line-1656"> for (int i = 0; i &lt; codes.length; i++) {</span>
<span class="source-line-no">1657</span><span id="line-1657"> assertEquals((i == 5) ? OperationStatusCode.BAD_FAMILY : OperationStatusCode.SUCCESS,</span>
<span class="source-line-no">1658</span><span id="line-1658"> codes[i].getOperationStatusCode());</span>
<span class="source-line-no">1659</span><span id="line-1659"> }</span>
<span class="source-line-no">1660</span><span id="line-1660"> rowLock4.release();</span>
<span class="source-line-no">1661</span><span id="line-1661"> }</span>
<span class="source-line-no">1662</span><span id="line-1662"></span>
<span class="source-line-no">1663</span><span id="line-1663"> private void waitForCounter(MetricsWALSource source, String metricName, long expectedCount)</span>
<span class="source-line-no">1664</span><span id="line-1664"> throws InterruptedException {</span>
<span class="source-line-no">1665</span><span id="line-1665"> long startWait = EnvironmentEdgeManager.currentTime();</span>
<span class="source-line-no">1666</span><span id="line-1666"> long currentCount;</span>
<span class="source-line-no">1667</span><span id="line-1667"> while ((currentCount = metricsAssertHelper.getCounter(metricName, source)) &lt; expectedCount) {</span>
<span class="source-line-no">1668</span><span id="line-1668"> Thread.sleep(100);</span>
<span class="source-line-no">1669</span><span id="line-1669"> if (EnvironmentEdgeManager.currentTime() - startWait &gt; 10000) {</span>
<span class="source-line-no">1670</span><span id="line-1670"> fail(String.format("Timed out waiting for '%s' &gt;= '%s', currentCount=%s", metricName,</span>
<span class="source-line-no">1671</span><span id="line-1671"> expectedCount, currentCount));</span>
<span class="source-line-no">1672</span><span id="line-1672"> }</span>
<span class="source-line-no">1673</span><span id="line-1673"> }</span>
<span class="source-line-no">1674</span><span id="line-1674"> }</span>
<span class="source-line-no">1675</span><span id="line-1675"></span>
<span class="source-line-no">1676</span><span id="line-1676"> @Test</span>
<span class="source-line-no">1677</span><span id="line-1677"> public void testAtomicBatchPut() throws IOException {</span>
<span class="source-line-no">1678</span><span id="line-1678"> final Put[] puts = new Put[10];</span>
<span class="source-line-no">1679</span><span id="line-1679"> MetricsWALSource source = CompatibilitySingletonFactory.getInstance(MetricsWALSource.class);</span>
<span class="source-line-no">1680</span><span id="line-1680"> long syncs = prepareRegionForBachPut(puts, source, false);</span>
<span class="source-line-no">1681</span><span id="line-1681"></span>
<span class="source-line-no">1682</span><span id="line-1682"> // 1. Straight forward case, should succeed</span>
<span class="source-line-no">1683</span><span id="line-1683"> OperationStatus[] codes = this.region.batchMutate(puts, true);</span>
<span class="source-line-no">1684</span><span id="line-1684"> assertEquals(10, codes.length);</span>
<span class="source-line-no">1685</span><span id="line-1685"> for (int i = 0; i &lt; 10; i++) {</span>
<span class="source-line-no">1686</span><span id="line-1686"> assertEquals(OperationStatusCode.SUCCESS, codes[i].getOperationStatusCode());</span>
<span class="source-line-no">1687</span><span id="line-1687"> }</span>
<span class="source-line-no">1688</span><span id="line-1688"> metricsAssertHelper.assertCounter("syncTimeNumOps", syncs + 1, source);</span>
<span class="source-line-no">1689</span><span id="line-1689"></span>
<span class="source-line-no">1690</span><span id="line-1690"> // 2. Failed to get lock</span>
<span class="source-line-no">1691</span><span id="line-1691"> RowLock lock = region.getRowLock(Bytes.toBytes("row_" + 3));</span>
<span class="source-line-no">1692</span><span id="line-1692"> // Method {@link HRegion#getRowLock(byte[])} is reentrant. As 'row_3' is locked in this</span>
<span class="source-line-no">1693</span><span id="line-1693"> // thread, need to run {@link HRegion#batchMutate(HRegion.BatchOperation)} in different thread</span>
<span class="source-line-no">1694</span><span id="line-1694"> MultithreadedTestUtil.TestContext ctx = new MultithreadedTestUtil.TestContext(CONF);</span>
<span class="source-line-no">1695</span><span id="line-1695"> final AtomicReference&lt;IOException&gt; retFromThread = new AtomicReference&lt;&gt;();</span>
<span class="source-line-no">1696</span><span id="line-1696"> final CountDownLatch finishedPuts = new CountDownLatch(1);</span>
<span class="source-line-no">1697</span><span id="line-1697"> TestThread putter = new TestThread(ctx) {</span>
<span class="source-line-no">1698</span><span id="line-1698"> @Override</span>
<span class="source-line-no">1699</span><span id="line-1699"> public void doWork() throws IOException {</span>
<span class="source-line-no">1700</span><span id="line-1700"> try {</span>
<span class="source-line-no">1701</span><span id="line-1701"> region.batchMutate(puts, true);</span>
<span class="source-line-no">1702</span><span id="line-1702"> } catch (IOException ioe) {</span>
<span class="source-line-no">1703</span><span id="line-1703"> LOG.error("test failed!", ioe);</span>
<span class="source-line-no">1704</span><span id="line-1704"> retFromThread.set(ioe);</span>
<span class="source-line-no">1705</span><span id="line-1705"> }</span>
<span class="source-line-no">1706</span><span id="line-1706"> finishedPuts.countDown();</span>
<span class="source-line-no">1707</span><span id="line-1707"> }</span>
<span class="source-line-no">1708</span><span id="line-1708"> };</span>
<span class="source-line-no">1709</span><span id="line-1709"> LOG.info("...starting put thread while holding locks");</span>
<span class="source-line-no">1710</span><span id="line-1710"> ctx.addThread(putter);</span>
<span class="source-line-no">1711</span><span id="line-1711"> ctx.startThreads();</span>
<span class="source-line-no">1712</span><span id="line-1712"> LOG.info("...waiting for batch puts while holding locks");</span>
<span class="source-line-no">1713</span><span id="line-1713"> try {</span>
<span class="source-line-no">1714</span><span id="line-1714"> finishedPuts.await();</span>
<span class="source-line-no">1715</span><span id="line-1715"> } catch (InterruptedException e) {</span>
<span class="source-line-no">1716</span><span id="line-1716"> LOG.error("Interrupted!", e);</span>
<span class="source-line-no">1717</span><span id="line-1717"> } finally {</span>
<span class="source-line-no">1718</span><span id="line-1718"> if (lock != null) {</span>
<span class="source-line-no">1719</span><span id="line-1719"> lock.release();</span>
<span class="source-line-no">1720</span><span id="line-1720"> }</span>
<span class="source-line-no">1721</span><span id="line-1721"> }</span>
<span class="source-line-no">1722</span><span id="line-1722"> assertNotNull(retFromThread.get());</span>
<span class="source-line-no">1723</span><span id="line-1723"> metricsAssertHelper.assertCounter("syncTimeNumOps", syncs + 1, source);</span>
<span class="source-line-no">1724</span><span id="line-1724"></span>
<span class="source-line-no">1725</span><span id="line-1725"> // 3. Exception thrown in validation</span>
<span class="source-line-no">1726</span><span id="line-1726"> LOG.info("Next a batch put with one invalid family");</span>
<span class="source-line-no">1727</span><span id="line-1727"> puts[5].addColumn(Bytes.toBytes("BAD_CF"), qual, value);</span>
<span class="source-line-no">1728</span><span id="line-1728"> thrown.expect(NoSuchColumnFamilyException.class);</span>
<span class="source-line-no">1729</span><span id="line-1729"> this.region.batchMutate(puts, true);</span>
<span class="source-line-no">1730</span><span id="line-1730"> }</span>
<span class="source-line-no">1731</span><span id="line-1731"></span>
<span class="source-line-no">1732</span><span id="line-1732"> @Test</span>
<span class="source-line-no">1733</span><span id="line-1733"> public void testBatchPutWithTsSlop() throws Exception {</span>
<span class="source-line-no">1734</span><span id="line-1734"> // add data with a timestamp that is too recent for range. Ensure assert</span>
<span class="source-line-no">1735</span><span id="line-1735"> CONF.setInt("hbase.hregion.keyvalue.timestamp.slop.millisecs", 1000);</span>
<span class="source-line-no">1736</span><span id="line-1736"> final Put[] puts = new Put[10];</span>
<span class="source-line-no">1737</span><span id="line-1737"> MetricsWALSource source = CompatibilitySingletonFactory.getInstance(MetricsWALSource.class);</span>
<span class="source-line-no">1738</span><span id="line-1738"></span>
<span class="source-line-no">1739</span><span id="line-1739"> long syncs = prepareRegionForBachPut(puts, source, true);</span>
<span class="source-line-no">1740</span><span id="line-1740"></span>
<span class="source-line-no">1741</span><span id="line-1741"> OperationStatus[] codes = this.region.batchMutate(puts);</span>
<span class="source-line-no">1742</span><span id="line-1742"> assertEquals(10, codes.length);</span>
<span class="source-line-no">1743</span><span id="line-1743"> for (int i = 0; i &lt; 10; i++) {</span>
<span class="source-line-no">1744</span><span id="line-1744"> assertEquals(OperationStatusCode.SANITY_CHECK_FAILURE, codes[i].getOperationStatusCode());</span>
<span class="source-line-no">1745</span><span id="line-1745"> }</span>
<span class="source-line-no">1746</span><span id="line-1746"> metricsAssertHelper.assertCounter("syncTimeNumOps", syncs, source);</span>
<span class="source-line-no">1747</span><span id="line-1747"> }</span>
<span class="source-line-no">1748</span><span id="line-1748"></span>
<span class="source-line-no">1749</span><span id="line-1749"> /** Returns syncs initial syncTimeNumOps */</span>
<span class="source-line-no">1750</span><span id="line-1750"> private long prepareRegionForBachPut(final Put[] puts, final MetricsWALSource source,</span>
<span class="source-line-no">1751</span><span id="line-1751"> boolean slop) throws IOException {</span>
<span class="source-line-no">1752</span><span id="line-1752"> this.region = initHRegion(tableName, method, CONF, COLUMN_FAMILY_BYTES);</span>
<span class="source-line-no">1753</span><span id="line-1753"></span>
<span class="source-line-no">1754</span><span id="line-1754"> LOG.info("First a batch put with all valid puts");</span>
<span class="source-line-no">1755</span><span id="line-1755"> for (int i = 0; i &lt; puts.length; i++) {</span>
<span class="source-line-no">1756</span><span id="line-1756"> puts[i] = slop</span>
<span class="source-line-no">1757</span><span id="line-1757"> ? new Put(Bytes.toBytes("row_" + i), Long.MAX_VALUE - 100)</span>
<span class="source-line-no">1758</span><span id="line-1758"> : new Put(Bytes.toBytes("row_" + i));</span>
<span class="source-line-no">1759</span><span id="line-1759"> puts[i].addColumn(COLUMN_FAMILY_BYTES, qual, value);</span>
<span class="source-line-no">1760</span><span id="line-1760"> }</span>
<span class="source-line-no">1761</span><span id="line-1761"></span>
<span class="source-line-no">1762</span><span id="line-1762"> long syncs = metricsAssertHelper.getCounter("syncTimeNumOps", source);</span>
<span class="source-line-no">1763</span><span id="line-1763"> metricsAssertHelper.assertCounter("syncTimeNumOps", syncs, source);</span>
<span class="source-line-no">1764</span><span id="line-1764"> return syncs;</span>
<span class="source-line-no">1765</span><span id="line-1765"> }</span>
<span class="source-line-no">1766</span><span id="line-1766"></span>
<span class="source-line-no">1767</span><span id="line-1767"> // ////////////////////////////////////////////////////////////////////////////</span>
<span class="source-line-no">1768</span><span id="line-1768"> // checkAndMutate tests</span>
<span class="source-line-no">1769</span><span id="line-1769"> // ////////////////////////////////////////////////////////////////////////////</span>
<span class="source-line-no">1770</span><span id="line-1770"> @Test</span>
<span class="source-line-no">1771</span><span id="line-1771"> @Deprecated</span>
<span class="source-line-no">1772</span><span id="line-1772"> public void testCheckAndMutate_WithEmptyRowValue() throws IOException {</span>
<span class="source-line-no">1773</span><span id="line-1773"> byte[] row1 = Bytes.toBytes("row1");</span>
<span class="source-line-no">1774</span><span id="line-1774"> byte[] fam1 = Bytes.toBytes("fam1");</span>
<span class="source-line-no">1775</span><span id="line-1775"> byte[] qf1 = Bytes.toBytes("qualifier");</span>
<span class="source-line-no">1776</span><span id="line-1776"> byte[] emptyVal = new byte[] {};</span>
<span class="source-line-no">1777</span><span id="line-1777"> byte[] val1 = Bytes.toBytes("value1");</span>
<span class="source-line-no">1778</span><span id="line-1778"> byte[] val2 = Bytes.toBytes("value2");</span>
<span class="source-line-no">1779</span><span id="line-1779"></span>
<span class="source-line-no">1780</span><span id="line-1780"> // Setting up region</span>
<span class="source-line-no">1781</span><span id="line-1781"> this.region = initHRegion(tableName, method, CONF, fam1);</span>
<span class="source-line-no">1782</span><span id="line-1782"> // Putting empty data in key</span>
<span class="source-line-no">1783</span><span id="line-1783"> Put put = new Put(row1);</span>
<span class="source-line-no">1784</span><span id="line-1784"> put.addColumn(fam1, qf1, emptyVal);</span>
<span class="source-line-no">1785</span><span id="line-1785"></span>
<span class="source-line-no">1786</span><span id="line-1786"> // checkAndPut with empty value</span>
<span class="source-line-no">1787</span><span id="line-1787"> boolean res = region.checkAndMutate(row1, fam1, qf1, CompareOperator.EQUAL,</span>
<span class="source-line-no">1788</span><span id="line-1788"> new BinaryComparator(emptyVal), put);</span>
<span class="source-line-no">1789</span><span id="line-1789"> assertTrue(res);</span>
<span class="source-line-no">1790</span><span id="line-1790"></span>
<span class="source-line-no">1791</span><span id="line-1791"> // Putting data in key</span>
<span class="source-line-no">1792</span><span id="line-1792"> put = new Put(row1);</span>
<span class="source-line-no">1793</span><span id="line-1793"> put.addColumn(fam1, qf1, val1);</span>
<span class="source-line-no">1794</span><span id="line-1794"></span>
<span class="source-line-no">1795</span><span id="line-1795"> // checkAndPut with correct value</span>
<span class="source-line-no">1796</span><span id="line-1796"> res = region.checkAndMutate(row1, fam1, qf1, CompareOperator.EQUAL,</span>
<span class="source-line-no">1797</span><span id="line-1797"> new BinaryComparator(emptyVal), put);</span>
<span class="source-line-no">1798</span><span id="line-1798"> assertTrue(res);</span>
<span class="source-line-no">1799</span><span id="line-1799"></span>
<span class="source-line-no">1800</span><span id="line-1800"> // not empty anymore</span>
<span class="source-line-no">1801</span><span id="line-1801"> res = region.checkAndMutate(row1, fam1, qf1, CompareOperator.EQUAL,</span>
<span class="source-line-no">1802</span><span id="line-1802"> new BinaryComparator(emptyVal), put);</span>
<span class="source-line-no">1803</span><span id="line-1803"> assertFalse(res);</span>
<span class="source-line-no">1804</span><span id="line-1804"></span>
<span class="source-line-no">1805</span><span id="line-1805"> Delete delete = new Delete(row1);</span>
<span class="source-line-no">1806</span><span id="line-1806"> delete.addColumn(fam1, qf1);</span>
<span class="source-line-no">1807</span><span id="line-1807"> res = region.checkAndMutate(row1, fam1, qf1, CompareOperator.EQUAL,</span>
<span class="source-line-no">1808</span><span id="line-1808"> new BinaryComparator(emptyVal), delete);</span>
<span class="source-line-no">1809</span><span id="line-1809"> assertFalse(res);</span>
<span class="source-line-no">1810</span><span id="line-1810"></span>
<span class="source-line-no">1811</span><span id="line-1811"> put = new Put(row1);</span>
<span class="source-line-no">1812</span><span id="line-1812"> put.addColumn(fam1, qf1, val2);</span>
<span class="source-line-no">1813</span><span id="line-1813"> // checkAndPut with correct value</span>
<span class="source-line-no">1814</span><span id="line-1814"> res = region.checkAndMutate(row1, fam1, qf1, CompareOperator.EQUAL, new BinaryComparator(val1),</span>
<span class="source-line-no">1815</span><span id="line-1815"> put);</span>
<span class="source-line-no">1816</span><span id="line-1816"> assertTrue(res);</span>
<span class="source-line-no">1817</span><span id="line-1817"></span>
<span class="source-line-no">1818</span><span id="line-1818"> // checkAndDelete with correct value</span>
<span class="source-line-no">1819</span><span id="line-1819"> delete = new Delete(row1);</span>
<span class="source-line-no">1820</span><span id="line-1820"> delete.addColumn(fam1, qf1);</span>
<span class="source-line-no">1821</span><span id="line-1821"> delete.addColumn(fam1, qf1);</span>
<span class="source-line-no">1822</span><span id="line-1822"> res = region.checkAndMutate(row1, fam1, qf1, CompareOperator.EQUAL, new BinaryComparator(val2),</span>
<span class="source-line-no">1823</span><span id="line-1823"> delete);</span>
<span class="source-line-no">1824</span><span id="line-1824"> assertTrue(res);</span>
<span class="source-line-no">1825</span><span id="line-1825"></span>
<span class="source-line-no">1826</span><span id="line-1826"> delete = new Delete(row1);</span>
<span class="source-line-no">1827</span><span id="line-1827"> res = region.checkAndMutate(row1, fam1, qf1, CompareOperator.EQUAL,</span>
<span class="source-line-no">1828</span><span id="line-1828"> new BinaryComparator(emptyVal), delete);</span>
<span class="source-line-no">1829</span><span id="line-1829"> assertTrue(res);</span>
<span class="source-line-no">1830</span><span id="line-1830"></span>
<span class="source-line-no">1831</span><span id="line-1831"> // checkAndPut looking for a null value</span>
<span class="source-line-no">1832</span><span id="line-1832"> put = new Put(row1);</span>
<span class="source-line-no">1833</span><span id="line-1833"> put.addColumn(fam1, qf1, val1);</span>
<span class="source-line-no">1834</span><span id="line-1834"></span>
<span class="source-line-no">1835</span><span id="line-1835"> res = region.checkAndMutate(row1, fam1, qf1, CompareOperator.EQUAL, new NullComparator(), put);</span>
<span class="source-line-no">1836</span><span id="line-1836"> assertTrue(res);</span>
<span class="source-line-no">1837</span><span id="line-1837"> }</span>
<span class="source-line-no">1838</span><span id="line-1838"></span>
<span class="source-line-no">1839</span><span id="line-1839"> @Test</span>
<span class="source-line-no">1840</span><span id="line-1840"> @Deprecated</span>
<span class="source-line-no">1841</span><span id="line-1841"> public void testCheckAndMutate_WithWrongValue() throws IOException {</span>
<span class="source-line-no">1842</span><span id="line-1842"> byte[] row1 = Bytes.toBytes("row1");</span>
<span class="source-line-no">1843</span><span id="line-1843"> byte[] fam1 = Bytes.toBytes("fam1");</span>
<span class="source-line-no">1844</span><span id="line-1844"> byte[] qf1 = Bytes.toBytes("qualifier");</span>
<span class="source-line-no">1845</span><span id="line-1845"> byte[] val1 = Bytes.toBytes("value1");</span>
<span class="source-line-no">1846</span><span id="line-1846"> byte[] val2 = Bytes.toBytes("value2");</span>
<span class="source-line-no">1847</span><span id="line-1847"> BigDecimal bd1 = new BigDecimal(Double.MAX_VALUE);</span>
<span class="source-line-no">1848</span><span id="line-1848"> BigDecimal bd2 = new BigDecimal(Double.MIN_VALUE);</span>
<span class="source-line-no">1849</span><span id="line-1849"></span>
<span class="source-line-no">1850</span><span id="line-1850"> // Setting up region</span>
<span class="source-line-no">1851</span><span id="line-1851"> this.region = initHRegion(tableName, method, CONF, fam1);</span>
<span class="source-line-no">1852</span><span id="line-1852"> // Putting data in key</span>
<span class="source-line-no">1853</span><span id="line-1853"> Put put = new Put(row1);</span>
<span class="source-line-no">1854</span><span id="line-1854"> put.addColumn(fam1, qf1, val1);</span>
<span class="source-line-no">1855</span><span id="line-1855"> region.put(put);</span>
<span class="source-line-no">1856</span><span id="line-1856"></span>
<span class="source-line-no">1857</span><span id="line-1857"> // checkAndPut with wrong value</span>
<span class="source-line-no">1858</span><span id="line-1858"> boolean res = region.checkAndMutate(row1, fam1, qf1, CompareOperator.EQUAL,</span>
<span class="source-line-no">1859</span><span id="line-1859"> new BinaryComparator(val2), put);</span>
<span class="source-line-no">1860</span><span id="line-1860"> assertEquals(false, res);</span>
<span class="source-line-no">1861</span><span id="line-1861"></span>
<span class="source-line-no">1862</span><span id="line-1862"> // checkAndDelete with wrong value</span>
<span class="source-line-no">1863</span><span id="line-1863"> Delete delete = new Delete(row1);</span>
<span class="source-line-no">1864</span><span id="line-1864"> delete.addFamily(fam1);</span>
<span class="source-line-no">1865</span><span id="line-1865"> res = region.checkAndMutate(row1, fam1, qf1, CompareOperator.EQUAL, new BinaryComparator(val2),</span>
<span class="source-line-no">1866</span><span id="line-1866"> put);</span>
<span class="source-line-no">1867</span><span id="line-1867"> assertEquals(false, res);</span>
<span class="source-line-no">1868</span><span id="line-1868"></span>
<span class="source-line-no">1869</span><span id="line-1869"> // Putting data in key</span>
<span class="source-line-no">1870</span><span id="line-1870"> put = new Put(row1);</span>
<span class="source-line-no">1871</span><span id="line-1871"> put.addColumn(fam1, qf1, Bytes.toBytes(bd1));</span>
<span class="source-line-no">1872</span><span id="line-1872"> region.put(put);</span>
<span class="source-line-no">1873</span><span id="line-1873"></span>
<span class="source-line-no">1874</span><span id="line-1874"> // checkAndPut with wrong value</span>
<span class="source-line-no">1875</span><span id="line-1875"> res = region.checkAndMutate(row1, fam1, qf1, CompareOperator.EQUAL,</span>
<span class="source-line-no">1876</span><span id="line-1876"> new BigDecimalComparator(bd2), put);</span>
<span class="source-line-no">1877</span><span id="line-1877"> assertEquals(false, res);</span>
<span class="source-line-no">1878</span><span id="line-1878"></span>
<span class="source-line-no">1879</span><span id="line-1879"> // checkAndDelete with wrong value</span>
<span class="source-line-no">1880</span><span id="line-1880"> delete = new Delete(row1);</span>
<span class="source-line-no">1881</span><span id="line-1881"> delete.addFamily(fam1);</span>
<span class="source-line-no">1882</span><span id="line-1882"> res = region.checkAndMutate(row1, fam1, qf1, CompareOperator.EQUAL,</span>
<span class="source-line-no">1883</span><span id="line-1883"> new BigDecimalComparator(bd2), put);</span>
<span class="source-line-no">1884</span><span id="line-1884"> assertEquals(false, res);</span>
<span class="source-line-no">1885</span><span id="line-1885"> }</span>
<span class="source-line-no">1886</span><span id="line-1886"></span>
<span class="source-line-no">1887</span><span id="line-1887"> @Test</span>
<span class="source-line-no">1888</span><span id="line-1888"> @Deprecated</span>
<span class="source-line-no">1889</span><span id="line-1889"> public void testCheckAndMutate_WithCorrectValue() throws IOException {</span>
<span class="source-line-no">1890</span><span id="line-1890"> byte[] row1 = Bytes.toBytes("row1");</span>
<span class="source-line-no">1891</span><span id="line-1891"> byte[] fam1 = Bytes.toBytes("fam1");</span>
<span class="source-line-no">1892</span><span id="line-1892"> byte[] qf1 = Bytes.toBytes("qualifier");</span>
<span class="source-line-no">1893</span><span id="line-1893"> byte[] val1 = Bytes.toBytes("value1");</span>
<span class="source-line-no">1894</span><span id="line-1894"> BigDecimal bd1 = new BigDecimal(Double.MIN_VALUE);</span>
<span class="source-line-no">1895</span><span id="line-1895"></span>
<span class="source-line-no">1896</span><span id="line-1896"> // Setting up region</span>
<span class="source-line-no">1897</span><span id="line-1897"> this.region = initHRegion(tableName, method, CONF, fam1);</span>
<span class="source-line-no">1898</span><span id="line-1898"> // Putting data in key</span>
<span class="source-line-no">1899</span><span id="line-1899"> long now = EnvironmentEdgeManager.currentTime();</span>
<span class="source-line-no">1900</span><span id="line-1900"> Put put = new Put(row1);</span>
<span class="source-line-no">1901</span><span id="line-1901"> put.addColumn(fam1, qf1, now, val1);</span>
<span class="source-line-no">1902</span><span id="line-1902"> region.put(put);</span>
<span class="source-line-no">1903</span><span id="line-1903"></span>
<span class="source-line-no">1904</span><span id="line-1904"> // checkAndPut with correct value</span>
<span class="source-line-no">1905</span><span id="line-1905"> boolean res = region.checkAndMutate(row1, fam1, qf1, CompareOperator.EQUAL,</span>
<span class="source-line-no">1906</span><span id="line-1906"> new BinaryComparator(val1), put);</span>
<span class="source-line-no">1907</span><span id="line-1907"> assertEquals("First", true, res);</span>
<span class="source-line-no">1908</span><span id="line-1908"></span>
<span class="source-line-no">1909</span><span id="line-1909"> // checkAndDelete with correct value</span>
<span class="source-line-no">1910</span><span id="line-1910"> Delete delete = new Delete(row1, now + 1);</span>
<span class="source-line-no">1911</span><span id="line-1911"> delete.addColumn(fam1, qf1);</span>
<span class="source-line-no">1912</span><span id="line-1912"> res = region.checkAndMutate(row1, fam1, qf1, CompareOperator.EQUAL, new BinaryComparator(val1),</span>
<span class="source-line-no">1913</span><span id="line-1913"> delete);</span>
<span class="source-line-no">1914</span><span id="line-1914"> assertEquals("Delete", true, res);</span>
<span class="source-line-no">1915</span><span id="line-1915"></span>
<span class="source-line-no">1916</span><span id="line-1916"> // Putting data in key</span>
<span class="source-line-no">1917</span><span id="line-1917"> put = new Put(row1);</span>
<span class="source-line-no">1918</span><span id="line-1918"> put.addColumn(fam1, qf1, now + 2, Bytes.toBytes(bd1));</span>
<span class="source-line-no">1919</span><span id="line-1919"> region.put(put);</span>
<span class="source-line-no">1920</span><span id="line-1920"></span>
<span class="source-line-no">1921</span><span id="line-1921"> // checkAndPut with correct value</span>
<span class="source-line-no">1922</span><span id="line-1922"> res = region.checkAndMutate(row1, fam1, qf1, CompareOperator.EQUAL,</span>
<span class="source-line-no">1923</span><span id="line-1923"> new BigDecimalComparator(bd1), put);</span>
<span class="source-line-no">1924</span><span id="line-1924"> assertEquals("Second put", true, res);</span>
<span class="source-line-no">1925</span><span id="line-1925"></span>
<span class="source-line-no">1926</span><span id="line-1926"> // checkAndDelete with correct value</span>
<span class="source-line-no">1927</span><span id="line-1927"> delete = new Delete(row1, now + 3);</span>
<span class="source-line-no">1928</span><span id="line-1928"> delete.addColumn(fam1, qf1);</span>
<span class="source-line-no">1929</span><span id="line-1929"> res = region.checkAndMutate(row1, fam1, qf1, CompareOperator.EQUAL,</span>
<span class="source-line-no">1930</span><span id="line-1930"> new BigDecimalComparator(bd1), delete);</span>
<span class="source-line-no">1931</span><span id="line-1931"> assertEquals("Second delete", true, res);</span>
<span class="source-line-no">1932</span><span id="line-1932"> }</span>
<span class="source-line-no">1933</span><span id="line-1933"></span>
<span class="source-line-no">1934</span><span id="line-1934"> @Test</span>
<span class="source-line-no">1935</span><span id="line-1935"> @Deprecated</span>
<span class="source-line-no">1936</span><span id="line-1936"> public void testCheckAndMutate_WithNonEqualCompareOp() throws IOException {</span>
<span class="source-line-no">1937</span><span id="line-1937"> byte[] row1 = Bytes.toBytes("row1");</span>
<span class="source-line-no">1938</span><span id="line-1938"> byte[] fam1 = Bytes.toBytes("fam1");</span>
<span class="source-line-no">1939</span><span id="line-1939"> byte[] qf1 = Bytes.toBytes("qualifier");</span>
<span class="source-line-no">1940</span><span id="line-1940"> byte[] val1 = Bytes.toBytes("value1");</span>
<span class="source-line-no">1941</span><span id="line-1941"> byte[] val2 = Bytes.toBytes("value2");</span>
<span class="source-line-no">1942</span><span id="line-1942"> byte[] val3 = Bytes.toBytes("value3");</span>
<span class="source-line-no">1943</span><span id="line-1943"> byte[] val4 = Bytes.toBytes("value4");</span>
<span class="source-line-no">1944</span><span id="line-1944"></span>
<span class="source-line-no">1945</span><span id="line-1945"> // Setting up region</span>
<span class="source-line-no">1946</span><span id="line-1946"> this.region = initHRegion(tableName, method, CONF, fam1);</span>
<span class="source-line-no">1947</span><span id="line-1947"> // Putting val3 in key</span>
<span class="source-line-no">1948</span><span id="line-1948"> Put put = new Put(row1);</span>
<span class="source-line-no">1949</span><span id="line-1949"> put.addColumn(fam1, qf1, val3);</span>
<span class="source-line-no">1950</span><span id="line-1950"> region.put(put);</span>
<span class="source-line-no">1951</span><span id="line-1951"></span>
<span class="source-line-no">1952</span><span id="line-1952"> // Test CompareOp.LESS: original = val3, compare with val3, fail</span>
<span class="source-line-no">1953</span><span id="line-1953"> boolean res =</span>
<span class="source-line-no">1954</span><span id="line-1954"> region.checkAndMutate(row1, fam1, qf1, CompareOperator.LESS, new BinaryComparator(val3), put);</span>
<span class="source-line-no">1955</span><span id="line-1955"> assertEquals(false, res);</span>
<span class="source-line-no">1956</span><span id="line-1956"></span>
<span class="source-line-no">1957</span><span id="line-1957"> // Test CompareOp.LESS: original = val3, compare with val4, fail</span>
<span class="source-line-no">1958</span><span id="line-1958"> res =</span>
<span class="source-line-no">1959</span><span id="line-1959"> region.checkAndMutate(row1, fam1, qf1, CompareOperator.LESS, new BinaryComparator(val4), put);</span>
<span class="source-line-no">1960</span><span id="line-1960"> assertEquals(false, res);</span>
<span class="source-line-no">1961</span><span id="line-1961"></span>
<span class="source-line-no">1962</span><span id="line-1962"> // Test CompareOp.LESS: original = val3, compare with val2,</span>
<span class="source-line-no">1963</span><span id="line-1963"> // succeed (now value = val2)</span>
<span class="source-line-no">1964</span><span id="line-1964"> put = new Put(row1);</span>
<span class="source-line-no">1965</span><span id="line-1965"> put.addColumn(fam1, qf1, val2);</span>
<span class="source-line-no">1966</span><span id="line-1966"> res =</span>
<span class="source-line-no">1967</span><span id="line-1967"> region.checkAndMutate(row1, fam1, qf1, CompareOperator.LESS, new BinaryComparator(val2), put);</span>
<span class="source-line-no">1968</span><span id="line-1968"> assertEquals(true, res);</span>
<span class="source-line-no">1969</span><span id="line-1969"></span>
<span class="source-line-no">1970</span><span id="line-1970"> // Test CompareOp.LESS_OR_EQUAL: original = val2, compare with val3, fail</span>
<span class="source-line-no">1971</span><span id="line-1971"> res = region.checkAndMutate(row1, fam1, qf1, CompareOperator.LESS_OR_EQUAL,</span>
<span class="source-line-no">1972</span><span id="line-1972"> new BinaryComparator(val3), put);</span>
<span class="source-line-no">1973</span><span id="line-1973"> assertEquals(false, res);</span>
<span class="source-line-no">1974</span><span id="line-1974"></span>
<span class="source-line-no">1975</span><span id="line-1975"> // Test CompareOp.LESS_OR_EQUAL: original = val2, compare with val2,</span>
<span class="source-line-no">1976</span><span id="line-1976"> // succeed (value still = val2)</span>
<span class="source-line-no">1977</span><span id="line-1977"> res = region.checkAndMutate(row1, fam1, qf1, CompareOperator.LESS_OR_EQUAL,</span>
<span class="source-line-no">1978</span><span id="line-1978"> new BinaryComparator(val2), put);</span>
<span class="source-line-no">1979</span><span id="line-1979"> assertEquals(true, res);</span>
<span class="source-line-no">1980</span><span id="line-1980"></span>
<span class="source-line-no">1981</span><span id="line-1981"> // Test CompareOp.LESS_OR_EQUAL: original = val2, compare with val1,</span>
<span class="source-line-no">1982</span><span id="line-1982"> // succeed (now value = val3)</span>
<span class="source-line-no">1983</span><span id="line-1983"> put = new Put(row1);</span>
<span class="source-line-no">1984</span><span id="line-1984"> put.addColumn(fam1, qf1, val3);</span>
<span class="source-line-no">1985</span><span id="line-1985"> res = region.checkAndMutate(row1, fam1, qf1, CompareOperator.LESS_OR_EQUAL,</span>
<span class="source-line-no">1986</span><span id="line-1986"> new BinaryComparator(val1), put);</span>
<span class="source-line-no">1987</span><span id="line-1987"> assertEquals(true, res);</span>
<span class="source-line-no">1988</span><span id="line-1988"></span>
<span class="source-line-no">1989</span><span id="line-1989"> // Test CompareOp.GREATER: original = val3, compare with val3, fail</span>
<span class="source-line-no">1990</span><span id="line-1990"> res = region.checkAndMutate(row1, fam1, qf1, CompareOperator.GREATER,</span>
<span class="source-line-no">1991</span><span id="line-1991"> new BinaryComparator(val3), put);</span>
<span class="source-line-no">1992</span><span id="line-1992"> assertEquals(false, res);</span>
<span class="source-line-no">1993</span><span id="line-1993"></span>
<span class="source-line-no">1994</span><span id="line-1994"> // Test CompareOp.GREATER: original = val3, compare with val2, fail</span>
<span class="source-line-no">1995</span><span id="line-1995"> res = region.checkAndMutate(row1, fam1, qf1, CompareOperator.GREATER,</span>
<span class="source-line-no">1996</span><span id="line-1996"> new BinaryComparator(val2), put);</span>
<span class="source-line-no">1997</span><span id="line-1997"> assertEquals(false, res);</span>
<span class="source-line-no">1998</span><span id="line-1998"></span>
<span class="source-line-no">1999</span><span id="line-1999"> // Test CompareOp.GREATER: original = val3, compare with val4,</span>
<span class="source-line-no">2000</span><span id="line-2000"> // succeed (now value = val2)</span>
<span class="source-line-no">2001</span><span id="line-2001"> put = new Put(row1);</span>
<span class="source-line-no">2002</span><span id="line-2002"> put.addColumn(fam1, qf1, val2);</span>
<span class="source-line-no">2003</span><span id="line-2003"> res = region.checkAndMutate(row1, fam1, qf1, CompareOperator.GREATER,</span>
<span class="source-line-no">2004</span><span id="line-2004"> new BinaryComparator(val4), put);</span>
<span class="source-line-no">2005</span><span id="line-2005"> assertEquals(true, res);</span>
<span class="source-line-no">2006</span><span id="line-2006"></span>
<span class="source-line-no">2007</span><span id="line-2007"> // Test CompareOp.GREATER_OR_EQUAL: original = val2, compare with val1, fail</span>
<span class="source-line-no">2008</span><span id="line-2008"> res = region.checkAndMutate(row1, fam1, qf1, CompareOperator.GREATER_OR_EQUAL,</span>
<span class="source-line-no">2009</span><span id="line-2009"> new BinaryComparator(val1), put);</span>
<span class="source-line-no">2010</span><span id="line-2010"> assertEquals(false, res);</span>
<span class="source-line-no">2011</span><span id="line-2011"></span>
<span class="source-line-no">2012</span><span id="line-2012"> // Test CompareOp.GREATER_OR_EQUAL: original = val2, compare with val2,</span>
<span class="source-line-no">2013</span><span id="line-2013"> // succeed (value still = val2)</span>
<span class="source-line-no">2014</span><span id="line-2014"> res = region.checkAndMutate(row1, fam1, qf1, CompareOperator.GREATER_OR_EQUAL,</span>
<span class="source-line-no">2015</span><span id="line-2015"> new BinaryComparator(val2), put);</span>
<span class="source-line-no">2016</span><span id="line-2016"> assertEquals(true, res);</span>
<span class="source-line-no">2017</span><span id="line-2017"></span>
<span class="source-line-no">2018</span><span id="line-2018"> // Test CompareOp.GREATER_OR_EQUAL: original = val2, compare with val3, succeed</span>
<span class="source-line-no">2019</span><span id="line-2019"> res = region.checkAndMutate(row1, fam1, qf1, CompareOperator.GREATER_OR_EQUAL,</span>
<span class="source-line-no">2020</span><span id="line-2020"> new BinaryComparator(val3), put);</span>
<span class="source-line-no">2021</span><span id="line-2021"> assertEquals(true, res);</span>
<span class="source-line-no">2022</span><span id="line-2022"> }</span>
<span class="source-line-no">2023</span><span id="line-2023"></span>
<span class="source-line-no">2024</span><span id="line-2024"> @Test</span>
<span class="source-line-no">2025</span><span id="line-2025"> @Deprecated</span>
<span class="source-line-no">2026</span><span id="line-2026"> public void testCheckAndPut_ThatPutWasWritten() throws IOException {</span>
<span class="source-line-no">2027</span><span id="line-2027"> byte[] row1 = Bytes.toBytes("row1");</span>
<span class="source-line-no">2028</span><span id="line-2028"> byte[] fam1 = Bytes.toBytes("fam1");</span>
<span class="source-line-no">2029</span><span id="line-2029"> byte[] fam2 = Bytes.toBytes("fam2");</span>
<span class="source-line-no">2030</span><span id="line-2030"> byte[] qf1 = Bytes.toBytes("qualifier");</span>
<span class="source-line-no">2031</span><span id="line-2031"> byte[] val1 = Bytes.toBytes("value1");</span>
<span class="source-line-no">2032</span><span id="line-2032"> byte[] val2 = Bytes.toBytes("value2");</span>
<span class="source-line-no">2033</span><span id="line-2033"></span>
<span class="source-line-no">2034</span><span id="line-2034"> byte[][] families = { fam1, fam2 };</span>
<span class="source-line-no">2035</span><span id="line-2035"></span>
<span class="source-line-no">2036</span><span id="line-2036"> // Setting up region</span>
<span class="source-line-no">2037</span><span id="line-2037"> this.region = initHRegion(tableName, method, CONF, families);</span>
<span class="source-line-no">2038</span><span id="line-2038"> // Putting data in the key to check</span>
<span class="source-line-no">2039</span><span id="line-2039"> Put put = new Put(row1);</span>
<span class="source-line-no">2040</span><span id="line-2040"> put.addColumn(fam1, qf1, val1);</span>
<span class="source-line-no">2041</span><span id="line-2041"> region.put(put);</span>
<span class="source-line-no">2042</span><span id="line-2042"></span>
<span class="source-line-no">2043</span><span id="line-2043"> // Creating put to add</span>
<span class="source-line-no">2044</span><span id="line-2044"> long ts = EnvironmentEdgeManager.currentTime();</span>
<span class="source-line-no">2045</span><span id="line-2045"> KeyValue kv = new KeyValue(row1, fam2, qf1, ts, KeyValue.Type.Put, val2);</span>
<span class="source-line-no">2046</span><span id="line-2046"> put = new Put(row1);</span>
<span class="source-line-no">2047</span><span id="line-2047"> put.add(kv);</span>
<span class="source-line-no">2048</span><span id="line-2048"></span>
<span class="source-line-no">2049</span><span id="line-2049"> // checkAndPut with wrong value</span>
<span class="source-line-no">2050</span><span id="line-2050"> boolean res = region.checkAndMutate(row1, fam1, qf1, CompareOperator.EQUAL,</span>
<span class="source-line-no">2051</span><span id="line-2051"> new BinaryComparator(val1), put);</span>
<span class="source-line-no">2052</span><span id="line-2052"> assertEquals(true, res);</span>
<span class="source-line-no">2053</span><span id="line-2053"></span>
<span class="source-line-no">2054</span><span id="line-2054"> Get get = new Get(row1);</span>
<span class="source-line-no">2055</span><span id="line-2055"> get.addColumn(fam2, qf1);</span>
<span class="source-line-no">2056</span><span id="line-2056"> Cell[] actual = region.get(get).rawCells();</span>
<span class="source-line-no">2057</span><span id="line-2057"></span>
<span class="source-line-no">2058</span><span id="line-2058"> Cell[] expected = { kv };</span>
<span class="source-line-no">2059</span><span id="line-2059"></span>
<span class="source-line-no">2060</span><span id="line-2060"> assertEquals(expected.length, actual.length);</span>
<span class="source-line-no">2061</span><span id="line-2061"> for (int i = 0; i &lt; actual.length; i++) {</span>
<span class="source-line-no">2062</span><span id="line-2062"> assertEquals(expected[i], actual[i]);</span>
<span class="source-line-no">2063</span><span id="line-2063"> }</span>
<span class="source-line-no">2064</span><span id="line-2064"> }</span>
<span class="source-line-no">2065</span><span id="line-2065"></span>
<span class="source-line-no">2066</span><span id="line-2066"> @Test</span>
<span class="source-line-no">2067</span><span id="line-2067"> @Deprecated</span>
<span class="source-line-no">2068</span><span id="line-2068"> public void testCheckAndPut_wrongRowInPut() throws IOException {</span>
<span class="source-line-no">2069</span><span id="line-2069"> this.region = initHRegion(tableName, method, CONF, COLUMNS);</span>
<span class="source-line-no">2070</span><span id="line-2070"> Put put = new Put(row2);</span>
<span class="source-line-no">2071</span><span id="line-2071"> put.addColumn(fam1, qual1, value1);</span>
<span class="source-line-no">2072</span><span id="line-2072"> try {</span>
<span class="source-line-no">2073</span><span id="line-2073"> region.checkAndMutate(row, fam1, qual1, CompareOperator.EQUAL, new BinaryComparator(value2),</span>
<span class="source-line-no">2074</span><span id="line-2074"> put);</span>
<span class="source-line-no">2075</span><span id="line-2075"> fail();</span>
<span class="source-line-no">2076</span><span id="line-2076"> } catch (org.apache.hadoop.hbase.DoNotRetryIOException expected) {</span>
<span class="source-line-no">2077</span><span id="line-2077"> // expected exception.</span>
<span class="source-line-no">2078</span><span id="line-2078"> }</span>
<span class="source-line-no">2079</span><span id="line-2079"> }</span>
<span class="source-line-no">2080</span><span id="line-2080"></span>
<span class="source-line-no">2081</span><span id="line-2081"> @Test</span>
<span class="source-line-no">2082</span><span id="line-2082"> @Deprecated</span>
<span class="source-line-no">2083</span><span id="line-2083"> public void testCheckAndDelete_ThatDeleteWasWritten() throws IOException {</span>
<span class="source-line-no">2084</span><span id="line-2084"> byte[] row1 = Bytes.toBytes("row1");</span>
<span class="source-line-no">2085</span><span id="line-2085"> byte[] fam1 = Bytes.toBytes("fam1");</span>
<span class="source-line-no">2086</span><span id="line-2086"> byte[] fam2 = Bytes.toBytes("fam2");</span>
<span class="source-line-no">2087</span><span id="line-2087"> byte[] qf1 = Bytes.toBytes("qualifier1");</span>
<span class="source-line-no">2088</span><span id="line-2088"> byte[] qf2 = Bytes.toBytes("qualifier2");</span>
<span class="source-line-no">2089</span><span id="line-2089"> byte[] qf3 = Bytes.toBytes("qualifier3");</span>
<span class="source-line-no">2090</span><span id="line-2090"> byte[] val1 = Bytes.toBytes("value1");</span>
<span class="source-line-no">2091</span><span id="line-2091"> byte[] val2 = Bytes.toBytes("value2");</span>
<span class="source-line-no">2092</span><span id="line-2092"> byte[] val3 = Bytes.toBytes("value3");</span>
<span class="source-line-no">2093</span><span id="line-2093"> byte[] emptyVal = new byte[] {};</span>
<span class="source-line-no">2094</span><span id="line-2094"></span>
<span class="source-line-no">2095</span><span id="line-2095"> byte[][] families = { fam1, fam2 };</span>
<span class="source-line-no">2096</span><span id="line-2096"></span>
<span class="source-line-no">2097</span><span id="line-2097"> // Setting up region</span>
<span class="source-line-no">2098</span><span id="line-2098"> this.region = initHRegion(tableName, method, CONF, families);</span>
<span class="source-line-no">2099</span><span id="line-2099"> // Put content</span>
<span class="source-line-no">2100</span><span id="line-2100"> Put put = new Put(row1);</span>
<span class="source-line-no">2101</span><span id="line-2101"> put.addColumn(fam1, qf1, val1);</span>
<span class="source-line-no">2102</span><span id="line-2102"> region.put(put);</span>
<span class="source-line-no">2103</span><span id="line-2103"> Threads.sleep(2);</span>
<span class="source-line-no">2104</span><span id="line-2104"></span>
<span class="source-line-no">2105</span><span id="line-2105"> put = new Put(row1);</span>
<span class="source-line-no">2106</span><span id="line-2106"> put.addColumn(fam1, qf1, val2);</span>
<span class="source-line-no">2107</span><span id="line-2107"> put.addColumn(fam2, qf1, val3);</span>
<span class="source-line-no">2108</span><span id="line-2108"> put.addColumn(fam2, qf2, val2);</span>
<span class="source-line-no">2109</span><span id="line-2109"> put.addColumn(fam2, qf3, val1);</span>
<span class="source-line-no">2110</span><span id="line-2110"> put.addColumn(fam1, qf3, val1);</span>
<span class="source-line-no">2111</span><span id="line-2111"> region.put(put);</span>
<span class="source-line-no">2112</span><span id="line-2112"></span>
<span class="source-line-no">2113</span><span id="line-2113"> LOG.info("get={}", region.get(new Get(row1).addColumn(fam1, qf1)).toString());</span>
<span class="source-line-no">2114</span><span id="line-2114"></span>
<span class="source-line-no">2115</span><span id="line-2115"> // Multi-column delete</span>
<span class="source-line-no">2116</span><span id="line-2116"> Delete delete = new Delete(row1);</span>
<span class="source-line-no">2117</span><span id="line-2117"> delete.addColumn(fam1, qf1);</span>
<span class="source-line-no">2118</span><span id="line-2118"> delete.addColumn(fam2, qf1);</span>
<span class="source-line-no">2119</span><span id="line-2119"> delete.addColumn(fam1, qf3);</span>
<span class="source-line-no">2120</span><span id="line-2120"> boolean res = region.checkAndMutate(row1, fam1, qf1, CompareOperator.EQUAL,</span>
<span class="source-line-no">2121</span><span id="line-2121"> new BinaryComparator(val2), delete);</span>
<span class="source-line-no">2122</span><span id="line-2122"> assertEquals(true, res);</span>
<span class="source-line-no">2123</span><span id="line-2123"></span>
<span class="source-line-no">2124</span><span id="line-2124"> Get get = new Get(row1);</span>
<span class="source-line-no">2125</span><span id="line-2125"> get.addColumn(fam1, qf1);</span>
<span class="source-line-no">2126</span><span id="line-2126"> get.addColumn(fam1, qf3);</span>
<span class="source-line-no">2127</span><span id="line-2127"> get.addColumn(fam2, qf2);</span>
<span class="source-line-no">2128</span><span id="line-2128"> Result r = region.get(get);</span>
<span class="source-line-no">2129</span><span id="line-2129"> assertEquals(2, r.size());</span>
<span class="source-line-no">2130</span><span id="line-2130"> assertArrayEquals(val1, r.getValue(fam1, qf1));</span>
<span class="source-line-no">2131</span><span id="line-2131"> assertArrayEquals(val2, r.getValue(fam2, qf2));</span>
<span class="source-line-no">2132</span><span id="line-2132"></span>
<span class="source-line-no">2133</span><span id="line-2133"> // Family delete</span>
<span class="source-line-no">2134</span><span id="line-2134"> delete = new Delete(row1);</span>
<span class="source-line-no">2135</span><span id="line-2135"> delete.addFamily(fam2);</span>
<span class="source-line-no">2136</span><span id="line-2136"> res = region.checkAndMutate(row1, fam2, qf1, CompareOperator.EQUAL,</span>
<span class="source-line-no">2137</span><span id="line-2137"> new BinaryComparator(emptyVal), delete);</span>
<span class="source-line-no">2138</span><span id="line-2138"> assertEquals(true, res);</span>
<span class="source-line-no">2139</span><span id="line-2139"></span>
<span class="source-line-no">2140</span><span id="line-2140"> get = new Get(row1);</span>
<span class="source-line-no">2141</span><span id="line-2141"> r = region.get(get);</span>
<span class="source-line-no">2142</span><span id="line-2142"> assertEquals(1, r.size());</span>
<span class="source-line-no">2143</span><span id="line-2143"> assertArrayEquals(val1, r.getValue(fam1, qf1));</span>
<span class="source-line-no">2144</span><span id="line-2144"></span>
<span class="source-line-no">2145</span><span id="line-2145"> // Row delete</span>
<span class="source-line-no">2146</span><span id="line-2146"> delete = new Delete(row1);</span>
<span class="source-line-no">2147</span><span id="line-2147"> res = region.checkAndMutate(row1, fam1, qf1, CompareOperator.EQUAL, new BinaryComparator(val1),</span>
<span class="source-line-no">2148</span><span id="line-2148"> delete);</span>
<span class="source-line-no">2149</span><span id="line-2149"> assertEquals(true, res);</span>
<span class="source-line-no">2150</span><span id="line-2150"> get = new Get(row1);</span>
<span class="source-line-no">2151</span><span id="line-2151"> r = region.get(get);</span>
<span class="source-line-no">2152</span><span id="line-2152"> assertEquals(0, r.size());</span>
<span class="source-line-no">2153</span><span id="line-2153"> }</span>
<span class="source-line-no">2154</span><span id="line-2154"></span>
<span class="source-line-no">2155</span><span id="line-2155"> @Test</span>
<span class="source-line-no">2156</span><span id="line-2156"> @Deprecated</span>
<span class="source-line-no">2157</span><span id="line-2157"> public void testCheckAndMutate_WithFilters() throws Throwable {</span>
<span class="source-line-no">2158</span><span id="line-2158"> final byte[] FAMILY = Bytes.toBytes("fam");</span>
<span class="source-line-no">2159</span><span id="line-2159"></span>
<span class="source-line-no">2160</span><span id="line-2160"> // Setting up region</span>
<span class="source-line-no">2161</span><span id="line-2161"> this.region = initHRegion(tableName, method, CONF, FAMILY);</span>
<span class="source-line-no">2162</span><span id="line-2162"></span>
<span class="source-line-no">2163</span><span id="line-2163"> // Put one row</span>
<span class="source-line-no">2164</span><span id="line-2164"> Put put = new Put(row);</span>
<span class="source-line-no">2165</span><span id="line-2165"> put.addColumn(FAMILY, Bytes.toBytes("A"), Bytes.toBytes("a"));</span>
<span class="source-line-no">2166</span><span id="line-2166"> put.addColumn(FAMILY, Bytes.toBytes("B"), Bytes.toBytes("b"));</span>
<span class="source-line-no">2167</span><span id="line-2167"> put.addColumn(FAMILY, Bytes.toBytes("C"), Bytes.toBytes("c"));</span>
<span class="source-line-no">2168</span><span id="line-2168"> region.put(put);</span>
<span class="source-line-no">2169</span><span id="line-2169"></span>
<span class="source-line-no">2170</span><span id="line-2170"> // Put with success</span>
<span class="source-line-no">2171</span><span id="line-2171"> boolean ok = region.checkAndMutate(row,</span>
<span class="source-line-no">2172</span><span id="line-2172"> new FilterList(</span>
<span class="source-line-no">2173</span><span id="line-2173"> new SingleColumnValueFilter(FAMILY, Bytes.toBytes("A"), CompareOperator.EQUAL,</span>
<span class="source-line-no">2174</span><span id="line-2174"> Bytes.toBytes("a")),</span>
<span class="source-line-no">2175</span><span id="line-2175"> new SingleColumnValueFilter(FAMILY, Bytes.toBytes("B"), CompareOperator.EQUAL,</span>
<span class="source-line-no">2176</span><span id="line-2176"> Bytes.toBytes("b"))),</span>
<span class="source-line-no">2177</span><span id="line-2177"> new Put(row).addColumn(FAMILY, Bytes.toBytes("D"), Bytes.toBytes("d")));</span>
<span class="source-line-no">2178</span><span id="line-2178"> assertTrue(ok);</span>
<span class="source-line-no">2179</span><span id="line-2179"></span>
<span class="source-line-no">2180</span><span id="line-2180"> Result result = region.get(new Get(row).addColumn(FAMILY, Bytes.toBytes("D")));</span>
<span class="source-line-no">2181</span><span id="line-2181"> assertEquals("d", Bytes.toString(result.getValue(FAMILY, Bytes.toBytes("D"))));</span>
<span class="source-line-no">2182</span><span id="line-2182"></span>
<span class="source-line-no">2183</span><span id="line-2183"> // Put with failure</span>
<span class="source-line-no">2184</span><span id="line-2184"> ok = region.checkAndMutate(row,</span>
<span class="source-line-no">2185</span><span id="line-2185"> new FilterList(</span>
<span class="source-line-no">2186</span><span id="line-2186"> new SingleColumnValueFilter(FAMILY, Bytes.toBytes("A"), CompareOperator.EQUAL,</span>
<span class="source-line-no">2187</span><span id="line-2187"> Bytes.toBytes("a")),</span>
<span class="source-line-no">2188</span><span id="line-2188"> new SingleColumnValueFilter(FAMILY, Bytes.toBytes("B"), CompareOperator.EQUAL,</span>
<span class="source-line-no">2189</span><span id="line-2189"> Bytes.toBytes("c"))),</span>
<span class="source-line-no">2190</span><span id="line-2190"> new Put(row).addColumn(FAMILY, Bytes.toBytes("E"), Bytes.toBytes("e")));</span>
<span class="source-line-no">2191</span><span id="line-2191"> assertFalse(ok);</span>
<span class="source-line-no">2192</span><span id="line-2192"></span>
<span class="source-line-no">2193</span><span id="line-2193"> assertTrue(region.get(new Get(row).addColumn(FAMILY, Bytes.toBytes("E"))).isEmpty());</span>
<span class="source-line-no">2194</span><span id="line-2194"></span>
<span class="source-line-no">2195</span><span id="line-2195"> // Delete with success</span>
<span class="source-line-no">2196</span><span id="line-2196"> ok = region.checkAndMutate(row,</span>
<span class="source-line-no">2197</span><span id="line-2197"> new FilterList(</span>
<span class="source-line-no">2198</span><span id="line-2198"> new SingleColumnValueFilter(FAMILY, Bytes.toBytes("A"), CompareOperator.EQUAL,</span>
<span class="source-line-no">2199</span><span id="line-2199"> Bytes.toBytes("a")),</span>
<span class="source-line-no">2200</span><span id="line-2200"> new SingleColumnValueFilter(FAMILY, Bytes.toBytes("B"), CompareOperator.EQUAL,</span>
<span class="source-line-no">2201</span><span id="line-2201"> Bytes.toBytes("b"))),</span>
<span class="source-line-no">2202</span><span id="line-2202"> new Delete(row).addColumns(FAMILY, Bytes.toBytes("D")));</span>
<span class="source-line-no">2203</span><span id="line-2203"> assertTrue(ok);</span>
<span class="source-line-no">2204</span><span id="line-2204"></span>
<span class="source-line-no">2205</span><span id="line-2205"> assertTrue(region.get(new Get(row).addColumn(FAMILY, Bytes.toBytes("D"))).isEmpty());</span>
<span class="source-line-no">2206</span><span id="line-2206"></span>
<span class="source-line-no">2207</span><span id="line-2207"> // Mutate with success</span>
<span class="source-line-no">2208</span><span id="line-2208"> ok = region.checkAndRowMutate(row,</span>
<span class="source-line-no">2209</span><span id="line-2209"> new FilterList(</span>
<span class="source-line-no">2210</span><span id="line-2210"> new SingleColumnValueFilter(FAMILY, Bytes.toBytes("A"), CompareOperator.EQUAL,</span>
<span class="source-line-no">2211</span><span id="line-2211"> Bytes.toBytes("a")),</span>
<span class="source-line-no">2212</span><span id="line-2212"> new SingleColumnValueFilter(FAMILY, Bytes.toBytes("B"), CompareOperator.EQUAL,</span>
<span class="source-line-no">2213</span><span id="line-2213"> Bytes.toBytes("b"))),</span>
<span class="source-line-no">2214</span><span id="line-2214"> new RowMutations(row)</span>
<span class="source-line-no">2215</span><span id="line-2215"> .add((Mutation) new Put(row).addColumn(FAMILY, Bytes.toBytes("E"), Bytes.toBytes("e")))</span>
<span class="source-line-no">2216</span><span id="line-2216"> .add((Mutation) new Delete(row).addColumns(FAMILY, Bytes.toBytes("A"))));</span>
<span class="source-line-no">2217</span><span id="line-2217"> assertTrue(ok);</span>
<span class="source-line-no">2218</span><span id="line-2218"></span>
<span class="source-line-no">2219</span><span id="line-2219"> result = region.get(new Get(row).addColumn(FAMILY, Bytes.toBytes("E")));</span>
<span class="source-line-no">2220</span><span id="line-2220"> assertEquals("e", Bytes.toString(result.getValue(FAMILY, Bytes.toBytes("E"))));</span>
<span class="source-line-no">2221</span><span id="line-2221"></span>
<span class="source-line-no">2222</span><span id="line-2222"> assertTrue(region.get(new Get(row).addColumn(FAMILY, Bytes.toBytes("A"))).isEmpty());</span>
<span class="source-line-no">2223</span><span id="line-2223"> }</span>
<span class="source-line-no">2224</span><span id="line-2224"></span>
<span class="source-line-no">2225</span><span id="line-2225"> @Test</span>
<span class="source-line-no">2226</span><span id="line-2226"> @Deprecated</span>
<span class="source-line-no">2227</span><span id="line-2227"> public void testCheckAndMutate_WithFiltersAndTimeRange() throws Throwable {</span>
<span class="source-line-no">2228</span><span id="line-2228"> final byte[] FAMILY = Bytes.toBytes("fam");</span>
<span class="source-line-no">2229</span><span id="line-2229"></span>
<span class="source-line-no">2230</span><span id="line-2230"> // Setting up region</span>
<span class="source-line-no">2231</span><span id="line-2231"> this.region = initHRegion(tableName, method, CONF, FAMILY);</span>
<span class="source-line-no">2232</span><span id="line-2232"></span>
<span class="source-line-no">2233</span><span id="line-2233"> // Put with specifying the timestamp</span>
<span class="source-line-no">2234</span><span id="line-2234"> region.put(new Put(row).addColumn(FAMILY, Bytes.toBytes("A"), 100, Bytes.toBytes("a")));</span>
<span class="source-line-no">2235</span><span id="line-2235"></span>
<span class="source-line-no">2236</span><span id="line-2236"> // Put with success</span>
<span class="source-line-no">2237</span><span id="line-2237"> boolean ok = region.checkAndMutate(row,</span>
<span class="source-line-no">2238</span><span id="line-2238"> new SingleColumnValueFilter(FAMILY, Bytes.toBytes("A"), CompareOperator.EQUAL,</span>
<span class="source-line-no">2239</span><span id="line-2239"> Bytes.toBytes("a")),</span>
<span class="source-line-no">2240</span><span id="line-2240"> TimeRange.between(0, 101),</span>
<span class="source-line-no">2241</span><span id="line-2241"> new Put(row).addColumn(FAMILY, Bytes.toBytes("B"), Bytes.toBytes("b")));</span>
<span class="source-line-no">2242</span><span id="line-2242"> assertTrue(ok);</span>
<span class="source-line-no">2243</span><span id="line-2243"></span>
<span class="source-line-no">2244</span><span id="line-2244"> Result result = region.get(new Get(row).addColumn(FAMILY, Bytes.toBytes("B")));</span>
<span class="source-line-no">2245</span><span id="line-2245"> assertEquals("b", Bytes.toString(result.getValue(FAMILY, Bytes.toBytes("B"))));</span>
<span class="source-line-no">2246</span><span id="line-2246"></span>
<span class="source-line-no">2247</span><span id="line-2247"> // Put with failure</span>
<span class="source-line-no">2248</span><span id="line-2248"> ok = region.checkAndMutate(row,</span>
<span class="source-line-no">2249</span><span id="line-2249"> new SingleColumnValueFilter(FAMILY, Bytes.toBytes("A"), CompareOperator.EQUAL,</span>
<span class="source-line-no">2250</span><span id="line-2250"> Bytes.toBytes("a")),</span>
<span class="source-line-no">2251</span><span id="line-2251"> TimeRange.between(0, 100),</span>
<span class="source-line-no">2252</span><span id="line-2252"> new Put(row).addColumn(FAMILY, Bytes.toBytes("C"), Bytes.toBytes("c")));</span>
<span class="source-line-no">2253</span><span id="line-2253"> assertFalse(ok);</span>
<span class="source-line-no">2254</span><span id="line-2254"></span>
<span class="source-line-no">2255</span><span id="line-2255"> assertTrue(region.get(new Get(row).addColumn(FAMILY, Bytes.toBytes("C"))).isEmpty());</span>
<span class="source-line-no">2256</span><span id="line-2256"></span>
<span class="source-line-no">2257</span><span id="line-2257"> // Mutate with success</span>
<span class="source-line-no">2258</span><span id="line-2258"> ok = region.checkAndRowMutate(row,</span>
<span class="source-line-no">2259</span><span id="line-2259"> new SingleColumnValueFilter(</span>
<span class="source-line-no">2260</span><span id="line-2260"> FAMILY, Bytes.toBytes("A"), CompareOperator.EQUAL, Bytes.toBytes("a")),</span>
<span class="source-line-no">2261</span><span id="line-2261"> TimeRange.between(0, 101),</span>
<span class="source-line-no">2262</span><span id="line-2262"> new RowMutations(row)</span>
<span class="source-line-no">2263</span><span id="line-2263"> .add((Mutation) new Put(row).addColumn(FAMILY, Bytes.toBytes("D"), Bytes.toBytes("d")))</span>
<span class="source-line-no">2264</span><span id="line-2264"> .add((Mutation) new Delete(row).addColumns(FAMILY, Bytes.toBytes("A"))));</span>
<span class="source-line-no">2265</span><span id="line-2265"> assertTrue(ok);</span>
<span class="source-line-no">2266</span><span id="line-2266"></span>
<span class="source-line-no">2267</span><span id="line-2267"> result = region.get(new Get(row).addColumn(FAMILY, Bytes.toBytes("D")));</span>
<span class="source-line-no">2268</span><span id="line-2268"> assertEquals("d", Bytes.toString(result.getValue(FAMILY, Bytes.toBytes("D"))));</span>
<span class="source-line-no">2269</span><span id="line-2269"></span>
<span class="source-line-no">2270</span><span id="line-2270"> assertTrue(region.get(new Get(row).addColumn(FAMILY, Bytes.toBytes("A"))).isEmpty());</span>
<span class="source-line-no">2271</span><span id="line-2271"> }</span>
<span class="source-line-no">2272</span><span id="line-2272"></span>
<span class="source-line-no">2273</span><span id="line-2273"> @Test</span>
<span class="source-line-no">2274</span><span id="line-2274"> @Deprecated</span>
<span class="source-line-no">2275</span><span id="line-2275"> public void testCheckAndMutate_wrongMutationType() throws Throwable {</span>
<span class="source-line-no">2276</span><span id="line-2276"> // Setting up region</span>
<span class="source-line-no">2277</span><span id="line-2277"> this.region = initHRegion(tableName, method, CONF, fam1);</span>
<span class="source-line-no">2278</span><span id="line-2278"></span>
<span class="source-line-no">2279</span><span id="line-2279"> try {</span>
<span class="source-line-no">2280</span><span id="line-2280"> region.checkAndMutate(row, fam1, qual1, CompareOperator.EQUAL, new BinaryComparator(value1),</span>
<span class="source-line-no">2281</span><span id="line-2281"> new Increment(row).addColumn(fam1, qual1, 1));</span>
<span class="source-line-no">2282</span><span id="line-2282"> fail("should throw DoNotRetryIOException");</span>
<span class="source-line-no">2283</span><span id="line-2283"> } catch (DoNotRetryIOException e) {</span>
<span class="source-line-no">2284</span><span id="line-2284"> assertEquals("Unsupported mutate type: INCREMENT", e.getMessage());</span>
<span class="source-line-no">2285</span><span id="line-2285"> }</span>
<span class="source-line-no">2286</span><span id="line-2286"></span>
<span class="source-line-no">2287</span><span id="line-2287"> try {</span>
<span class="source-line-no">2288</span><span id="line-2288"> region.checkAndMutate(row,</span>
<span class="source-line-no">2289</span><span id="line-2289"> new SingleColumnValueFilter(fam1, qual1, CompareOperator.EQUAL, value1),</span>
<span class="source-line-no">2290</span><span id="line-2290"> new Increment(row).addColumn(fam1, qual1, 1));</span>
<span class="source-line-no">2291</span><span id="line-2291"> fail("should throw DoNotRetryIOException");</span>
<span class="source-line-no">2292</span><span id="line-2292"> } catch (DoNotRetryIOException e) {</span>
<span class="source-line-no">2293</span><span id="line-2293"> assertEquals("Unsupported mutate type: INCREMENT", e.getMessage());</span>
<span class="source-line-no">2294</span><span id="line-2294"> }</span>
<span class="source-line-no">2295</span><span id="line-2295"> }</span>
<span class="source-line-no">2296</span><span id="line-2296"></span>
<span class="source-line-no">2297</span><span id="line-2297"> @Test</span>
<span class="source-line-no">2298</span><span id="line-2298"> @Deprecated</span>
<span class="source-line-no">2299</span><span id="line-2299"> public void testCheckAndMutate_wrongRow() throws Throwable {</span>
<span class="source-line-no">2300</span><span id="line-2300"> final byte[] wrongRow = Bytes.toBytes("wrongRow");</span>
<span class="source-line-no">2301</span><span id="line-2301"></span>
<span class="source-line-no">2302</span><span id="line-2302"> // Setting up region</span>
<span class="source-line-no">2303</span><span id="line-2303"> this.region = initHRegion(tableName, method, CONF, fam1);</span>
<span class="source-line-no">2304</span><span id="line-2304"></span>
<span class="source-line-no">2305</span><span id="line-2305"> try {</span>
<span class="source-line-no">2306</span><span id="line-2306"> region.checkAndMutate(row, fam1, qual1, CompareOperator.EQUAL, new BinaryComparator(value1),</span>
<span class="source-line-no">2307</span><span id="line-2307"> new Put(wrongRow).addColumn(fam1, qual1, value1));</span>
<span class="source-line-no">2308</span><span id="line-2308"> fail("should throw DoNotRetryIOException");</span>
<span class="source-line-no">2309</span><span id="line-2309"> } catch (DoNotRetryIOException e) {</span>
<span class="source-line-no">2310</span><span id="line-2310"> assertEquals("The row of the action &lt;wrongRow&gt; doesn't match the original one &lt;rowA&gt;",</span>
<span class="source-line-no">2311</span><span id="line-2311"> e.getMessage());</span>
<span class="source-line-no">2312</span><span id="line-2312"> }</span>
<span class="source-line-no">2313</span><span id="line-2313"></span>
<span class="source-line-no">2314</span><span id="line-2314"> try {</span>
<span class="source-line-no">2315</span><span id="line-2315"> region.checkAndMutate(row,</span>
<span class="source-line-no">2316</span><span id="line-2316"> new SingleColumnValueFilter(fam1, qual1, CompareOperator.EQUAL, value1),</span>
<span class="source-line-no">2317</span><span id="line-2317"> new Put(wrongRow).addColumn(fam1, qual1, value1));</span>
<span class="source-line-no">2318</span><span id="line-2318"> fail("should throw DoNotRetryIOException");</span>
<span class="source-line-no">2319</span><span id="line-2319"> } catch (DoNotRetryIOException e) {</span>
<span class="source-line-no">2320</span><span id="line-2320"> assertEquals("The row of the action &lt;wrongRow&gt; doesn't match the original one &lt;rowA&gt;",</span>
<span class="source-line-no">2321</span><span id="line-2321"> e.getMessage());</span>
<span class="source-line-no">2322</span><span id="line-2322"> }</span>
<span class="source-line-no">2323</span><span id="line-2323"></span>
<span class="source-line-no">2324</span><span id="line-2324"> try {</span>
<span class="source-line-no">2325</span><span id="line-2325"> region.checkAndRowMutate(row, fam1, qual1, CompareOperator.EQUAL,</span>
<span class="source-line-no">2326</span><span id="line-2326"> new BinaryComparator(value1),</span>
<span class="source-line-no">2327</span><span id="line-2327"> new RowMutations(wrongRow).add((Mutation) new Put(wrongRow).addColumn(fam1, qual1, value1))</span>
<span class="source-line-no">2328</span><span id="line-2328"> .add((Mutation) new Delete(wrongRow).addColumns(fam1, qual2)));</span>
<span class="source-line-no">2329</span><span id="line-2329"> fail("should throw DoNotRetryIOException");</span>
<span class="source-line-no">2330</span><span id="line-2330"> } catch (DoNotRetryIOException e) {</span>
<span class="source-line-no">2331</span><span id="line-2331"> assertEquals("The row of the action &lt;wrongRow&gt; doesn't match the original one &lt;rowA&gt;",</span>
<span class="source-line-no">2332</span><span id="line-2332"> e.getMessage());</span>
<span class="source-line-no">2333</span><span id="line-2333"> }</span>
<span class="source-line-no">2334</span><span id="line-2334"></span>
<span class="source-line-no">2335</span><span id="line-2335"> try {</span>
<span class="source-line-no">2336</span><span id="line-2336"> region.checkAndRowMutate(row,</span>
<span class="source-line-no">2337</span><span id="line-2337"> new SingleColumnValueFilter(fam1, qual1, CompareOperator.EQUAL, value1),</span>
<span class="source-line-no">2338</span><span id="line-2338"> new RowMutations(wrongRow).add((Mutation) new Put(wrongRow).addColumn(fam1, qual1, value1))</span>
<span class="source-line-no">2339</span><span id="line-2339"> .add((Mutation) new Delete(wrongRow).addColumns(fam1, qual2)));</span>
<span class="source-line-no">2340</span><span id="line-2340"> fail("should throw DoNotRetryIOException");</span>
<span class="source-line-no">2341</span><span id="line-2341"> } catch (DoNotRetryIOException e) {</span>
<span class="source-line-no">2342</span><span id="line-2342"> assertEquals("The row of the action &lt;wrongRow&gt; doesn't match the original one &lt;rowA&gt;",</span>
<span class="source-line-no">2343</span><span id="line-2343"> e.getMessage());</span>
<span class="source-line-no">2344</span><span id="line-2344"> }</span>
<span class="source-line-no">2345</span><span id="line-2345"> }</span>
<span class="source-line-no">2346</span><span id="line-2346"></span>
<span class="source-line-no">2347</span><span id="line-2347"> @Test</span>
<span class="source-line-no">2348</span><span id="line-2348"> public void testCheckAndMutateWithEmptyRowValue() throws IOException {</span>
<span class="source-line-no">2349</span><span id="line-2349"> byte[] row1 = Bytes.toBytes("row1");</span>
<span class="source-line-no">2350</span><span id="line-2350"> byte[] fam1 = Bytes.toBytes("fam1");</span>
<span class="source-line-no">2351</span><span id="line-2351"> byte[] qf1 = Bytes.toBytes("qualifier");</span>
<span class="source-line-no">2352</span><span id="line-2352"> byte[] emptyVal = new byte[] {};</span>
<span class="source-line-no">2353</span><span id="line-2353"> byte[] val1 = Bytes.toBytes("value1");</span>
<span class="source-line-no">2354</span><span id="line-2354"> byte[] val2 = Bytes.toBytes("value2");</span>
<span class="source-line-no">2355</span><span id="line-2355"></span>
<span class="source-line-no">2356</span><span id="line-2356"> // Setting up region</span>
<span class="source-line-no">2357</span><span id="line-2357"> this.region = initHRegion(tableName, method, CONF, fam1);</span>
<span class="source-line-no">2358</span><span id="line-2358"> // Putting empty data in key</span>
<span class="source-line-no">2359</span><span id="line-2359"> Put put = new Put(row1);</span>
<span class="source-line-no">2360</span><span id="line-2360"> put.addColumn(fam1, qf1, emptyVal);</span>
<span class="source-line-no">2361</span><span id="line-2361"></span>
<span class="source-line-no">2362</span><span id="line-2362"> // checkAndPut with empty value</span>
<span class="source-line-no">2363</span><span id="line-2363"> CheckAndMutateResult res = region.checkAndMutate(CheckAndMutate.newBuilder(row1)</span>
<span class="source-line-no">2364</span><span id="line-2364"> .ifMatches(fam1, qf1, CompareOperator.EQUAL, emptyVal).build(put));</span>
<span class="source-line-no">2365</span><span id="line-2365"> assertTrue(res.isSuccess());</span>
<span class="source-line-no">2366</span><span id="line-2366"> assertNull(res.getResult());</span>
<span class="source-line-no">2367</span><span id="line-2367"></span>
<span class="source-line-no">2368</span><span id="line-2368"> // Putting data in key</span>
<span class="source-line-no">2369</span><span id="line-2369"> put = new Put(row1);</span>
<span class="source-line-no">2370</span><span id="line-2370"> put.addColumn(fam1, qf1, val1);</span>
<span class="source-line-no">2371</span><span id="line-2371"></span>
<span class="source-line-no">2372</span><span id="line-2372"> // checkAndPut with correct value</span>
<span class="source-line-no">2373</span><span id="line-2373"> res = region.checkAndMutate(CheckAndMutate.newBuilder(row1)</span>
<span class="source-line-no">2374</span><span id="line-2374"> .ifMatches(fam1, qf1, CompareOperator.EQUAL, emptyVal).build(put));</span>
<span class="source-line-no">2375</span><span id="line-2375"> assertTrue(res.isSuccess());</span>
<span class="source-line-no">2376</span><span id="line-2376"> assertNull(res.getResult());</span>
<span class="source-line-no">2377</span><span id="line-2377"></span>
<span class="source-line-no">2378</span><span id="line-2378"> // not empty anymore</span>
<span class="source-line-no">2379</span><span id="line-2379"> res = region.checkAndMutate(CheckAndMutate.newBuilder(row1)</span>
<span class="source-line-no">2380</span><span id="line-2380"> .ifMatches(fam1, qf1, CompareOperator.EQUAL, emptyVal).build(put));</span>
<span class="source-line-no">2381</span><span id="line-2381"> assertFalse(res.isSuccess());</span>
<span class="source-line-no">2382</span><span id="line-2382"> assertNull(res.getResult());</span>
<span class="source-line-no">2383</span><span id="line-2383"></span>
<span class="source-line-no">2384</span><span id="line-2384"> Delete delete = new Delete(row1);</span>
<span class="source-line-no">2385</span><span id="line-2385"> delete.addColumn(fam1, qf1);</span>
<span class="source-line-no">2386</span><span id="line-2386"> res = region.checkAndMutate(CheckAndMutate.newBuilder(row1)</span>
<span class="source-line-no">2387</span><span id="line-2387"> .ifMatches(fam1, qf1, CompareOperator.EQUAL, emptyVal).build(delete));</span>
<span class="source-line-no">2388</span><span id="line-2388"> assertFalse(res.isSuccess());</span>
<span class="source-line-no">2389</span><span id="line-2389"> assertNull(res.getResult());</span>
<span class="source-line-no">2390</span><span id="line-2390"></span>
<span class="source-line-no">2391</span><span id="line-2391"> put = new Put(row1);</span>
<span class="source-line-no">2392</span><span id="line-2392"> put.addColumn(fam1, qf1, val2);</span>
<span class="source-line-no">2393</span><span id="line-2393"> // checkAndPut with correct value</span>
<span class="source-line-no">2394</span><span id="line-2394"> res = region.checkAndMutate(</span>
<span class="source-line-no">2395</span><span id="line-2395"> CheckAndMutate.newBuilder(row1).ifMatches(fam1, qf1, CompareOperator.EQUAL, val1).build(put));</span>
<span class="source-line-no">2396</span><span id="line-2396"> assertTrue(res.isSuccess());</span>
<span class="source-line-no">2397</span><span id="line-2397"> assertNull(res.getResult());</span>
<span class="source-line-no">2398</span><span id="line-2398"></span>
<span class="source-line-no">2399</span><span id="line-2399"> // checkAndDelete with correct value</span>
<span class="source-line-no">2400</span><span id="line-2400"> delete = new Delete(row1);</span>
<span class="source-line-no">2401</span><span id="line-2401"> delete.addColumn(fam1, qf1);</span>
<span class="source-line-no">2402</span><span id="line-2402"> delete.addColumn(fam1, qf1);</span>
<span class="source-line-no">2403</span><span id="line-2403"> res = region.checkAndMutate(CheckAndMutate.newBuilder(row1)</span>
<span class="source-line-no">2404</span><span id="line-2404"> .ifMatches(fam1, qf1, CompareOperator.EQUAL, val2).build(delete));</span>
<span class="source-line-no">2405</span><span id="line-2405"> assertTrue(res.isSuccess());</span>
<span class="source-line-no">2406</span><span id="line-2406"> assertNull(res.getResult());</span>
<span class="source-line-no">2407</span><span id="line-2407"></span>
<span class="source-line-no">2408</span><span id="line-2408"> delete = new Delete(row1);</span>
<span class="source-line-no">2409</span><span id="line-2409"> res = region.checkAndMutate(CheckAndMutate.newBuilder(row1)</span>
<span class="source-line-no">2410</span><span id="line-2410"> .ifMatches(fam1, qf1, CompareOperator.EQUAL, emptyVal).build(delete));</span>
<span class="source-line-no">2411</span><span id="line-2411"> assertTrue(res.isSuccess());</span>
<span class="source-line-no">2412</span><span id="line-2412"> assertNull(res.getResult());</span>
<span class="source-line-no">2413</span><span id="line-2413"></span>
<span class="source-line-no">2414</span><span id="line-2414"> // checkAndPut looking for a null value</span>
<span class="source-line-no">2415</span><span id="line-2415"> put = new Put(row1);</span>
<span class="source-line-no">2416</span><span id="line-2416"> put.addColumn(fam1, qf1, val1);</span>
<span class="source-line-no">2417</span><span id="line-2417"></span>
<span class="source-line-no">2418</span><span id="line-2418"> res = region.checkAndMutate(CheckAndMutate.newBuilder(row1).ifNotExists(fam1, qf1).build(put));</span>
<span class="source-line-no">2419</span><span id="line-2419"> assertTrue(res.isSuccess());</span>
<span class="source-line-no">2420</span><span id="line-2420"> assertNull(res.getResult());</span>
<span class="source-line-no">2421</span><span id="line-2421"> }</span>
<span class="source-line-no">2422</span><span id="line-2422"></span>
<span class="source-line-no">2423</span><span id="line-2423"> @Test</span>
<span class="source-line-no">2424</span><span id="line-2424"> public void testCheckAndMutateWithWrongValue() throws IOException {</span>
<span class="source-line-no">2425</span><span id="line-2425"> byte[] row1 = Bytes.toBytes("row1");</span>
<span class="source-line-no">2426</span><span id="line-2426"> byte[] fam1 = Bytes.toBytes("fam1");</span>
<span class="source-line-no">2427</span><span id="line-2427"> byte[] qf1 = Bytes.toBytes("qualifier");</span>
<span class="source-line-no">2428</span><span id="line-2428"> byte[] val1 = Bytes.toBytes("value1");</span>
<span class="source-line-no">2429</span><span id="line-2429"> byte[] val2 = Bytes.toBytes("value2");</span>
<span class="source-line-no">2430</span><span id="line-2430"> BigDecimal bd1 = new BigDecimal(Double.MAX_VALUE);</span>
<span class="source-line-no">2431</span><span id="line-2431"> BigDecimal bd2 = new BigDecimal(Double.MIN_VALUE);</span>
<span class="source-line-no">2432</span><span id="line-2432"></span>
<span class="source-line-no">2433</span><span id="line-2433"> // Setting up region</span>
<span class="source-line-no">2434</span><span id="line-2434"> this.region = initHRegion(tableName, method, CONF, fam1);</span>
<span class="source-line-no">2435</span><span id="line-2435"> // Putting data in key</span>
<span class="source-line-no">2436</span><span id="line-2436"> Put put = new Put(row1);</span>
<span class="source-line-no">2437</span><span id="line-2437"> put.addColumn(fam1, qf1, val1);</span>
<span class="source-line-no">2438</span><span id="line-2438"> region.put(put);</span>
<span class="source-line-no">2439</span><span id="line-2439"></span>
<span class="source-line-no">2440</span><span id="line-2440"> // checkAndPut with wrong value</span>
<span class="source-line-no">2441</span><span id="line-2441"> CheckAndMutateResult res = region.checkAndMutate(</span>
<span class="source-line-no">2442</span><span id="line-2442"> CheckAndMutate.newBuilder(row1).ifMatches(fam1, qf1, CompareOperator.EQUAL, val2).build(put));</span>
<span class="source-line-no">2443</span><span id="line-2443"> assertFalse(res.isSuccess());</span>
<span class="source-line-no">2444</span><span id="line-2444"> assertNull(res.getResult());</span>
<span class="source-line-no">2445</span><span id="line-2445"></span>
<span class="source-line-no">2446</span><span id="line-2446"> // checkAndDelete with wrong value</span>
<span class="source-line-no">2447</span><span id="line-2447"> Delete delete = new Delete(row1);</span>
<span class="source-line-no">2448</span><span id="line-2448"> delete.addFamily(fam1);</span>
<span class="source-line-no">2449</span><span id="line-2449"> res = region.checkAndMutate(</span>
<span class="source-line-no">2450</span><span id="line-2450"> CheckAndMutate.newBuilder(row1).ifMatches(fam1, qf1, CompareOperator.EQUAL, val2).build(put));</span>
<span class="source-line-no">2451</span><span id="line-2451"> assertFalse(res.isSuccess());</span>
<span class="source-line-no">2452</span><span id="line-2452"> assertNull(res.getResult());</span>
<span class="source-line-no">2453</span><span id="line-2453"></span>
<span class="source-line-no">2454</span><span id="line-2454"> // Putting data in key</span>
<span class="source-line-no">2455</span><span id="line-2455"> put = new Put(row1);</span>
<span class="source-line-no">2456</span><span id="line-2456"> put.addColumn(fam1, qf1, Bytes.toBytes(bd1));</span>
<span class="source-line-no">2457</span><span id="line-2457"> region.put(put);</span>
<span class="source-line-no">2458</span><span id="line-2458"></span>
<span class="source-line-no">2459</span><span id="line-2459"> // checkAndPut with wrong value</span>
<span class="source-line-no">2460</span><span id="line-2460"> res = region.checkAndMutate(CheckAndMutate.newBuilder(row1)</span>
<span class="source-line-no">2461</span><span id="line-2461"> .ifMatches(fam1, qf1, CompareOperator.EQUAL, Bytes.toBytes(bd2)).build(put));</span>
<span class="source-line-no">2462</span><span id="line-2462"> assertFalse(res.isSuccess());</span>
<span class="source-line-no">2463</span><span id="line-2463"> assertNull(res.getResult());</span>
<span class="source-line-no">2464</span><span id="line-2464"></span>
<span class="source-line-no">2465</span><span id="line-2465"> // checkAndDelete with wrong value</span>
<span class="source-line-no">2466</span><span id="line-2466"> delete = new Delete(row1);</span>
<span class="source-line-no">2467</span><span id="line-2467"> delete.addFamily(fam1);</span>
<span class="source-line-no">2468</span><span id="line-2468"> res = region.checkAndMutate(CheckAndMutate.newBuilder(row1)</span>
<span class="source-line-no">2469</span><span id="line-2469"> .ifMatches(fam1, qf1, CompareOperator.EQUAL, Bytes.toBytes(bd2)).build(delete));</span>
<span class="source-line-no">2470</span><span id="line-2470"> assertFalse(res.isSuccess());</span>
<span class="source-line-no">2471</span><span id="line-2471"> assertNull(res.getResult());</span>
<span class="source-line-no">2472</span><span id="line-2472"> }</span>
<span class="source-line-no">2473</span><span id="line-2473"></span>
<span class="source-line-no">2474</span><span id="line-2474"> @Test</span>
<span class="source-line-no">2475</span><span id="line-2475"> public void testCheckAndMutateWithCorrectValue() throws IOException {</span>
<span class="source-line-no">2476</span><span id="line-2476"> byte[] row1 = Bytes.toBytes("row1");</span>
<span class="source-line-no">2477</span><span id="line-2477"> byte[] fam1 = Bytes.toBytes("fam1");</span>
<span class="source-line-no">2478</span><span id="line-2478"> byte[] qf1 = Bytes.toBytes("qualifier");</span>
<span class="source-line-no">2479</span><span id="line-2479"> byte[] val1 = Bytes.toBytes("value1");</span>
<span class="source-line-no">2480</span><span id="line-2480"> BigDecimal bd1 = new BigDecimal(Double.MIN_VALUE);</span>
<span class="source-line-no">2481</span><span id="line-2481"></span>
<span class="source-line-no">2482</span><span id="line-2482"> // Setting up region</span>
<span class="source-line-no">2483</span><span id="line-2483"> this.region = initHRegion(tableName, method, CONF, fam1);</span>
<span class="source-line-no">2484</span><span id="line-2484"> // Putting data in key</span>
<span class="source-line-no">2485</span><span id="line-2485"> long now = EnvironmentEdgeManager.currentTime();</span>
<span class="source-line-no">2486</span><span id="line-2486"> Put put = new Put(row1);</span>
<span class="source-line-no">2487</span><span id="line-2487"> put.addColumn(fam1, qf1, now, val1);</span>
<span class="source-line-no">2488</span><span id="line-2488"> region.put(put);</span>
<span class="source-line-no">2489</span><span id="line-2489"></span>
<span class="source-line-no">2490</span><span id="line-2490"> // checkAndPut with correct value</span>
<span class="source-line-no">2491</span><span id="line-2491"> CheckAndMutateResult res = region.checkAndMutate(</span>
<span class="source-line-no">2492</span><span id="line-2492"> CheckAndMutate.newBuilder(row1).ifMatches(fam1, qf1, CompareOperator.EQUAL, val1).build(put));</span>
<span class="source-line-no">2493</span><span id="line-2493"> assertTrue("First", res.isSuccess());</span>
<span class="source-line-no">2494</span><span id="line-2494"></span>
<span class="source-line-no">2495</span><span id="line-2495"> // checkAndDelete with correct value</span>
<span class="source-line-no">2496</span><span id="line-2496"> Delete delete = new Delete(row1, now + 1);</span>
<span class="source-line-no">2497</span><span id="line-2497"> delete.addColumn(fam1, qf1);</span>
<span class="source-line-no">2498</span><span id="line-2498"> res = region.checkAndMutate(CheckAndMutate.newBuilder(row1)</span>
<span class="source-line-no">2499</span><span id="line-2499"> .ifMatches(fam1, qf1, CompareOperator.EQUAL, val1).build(delete));</span>
<span class="source-line-no">2500</span><span id="line-2500"> assertTrue("Delete", res.isSuccess());</span>
<span class="source-line-no">2501</span><span id="line-2501"> assertNull(res.getResult());</span>
<span class="source-line-no">2502</span><span id="line-2502"></span>
<span class="source-line-no">2503</span><span id="line-2503"> // Putting data in key</span>
<span class="source-line-no">2504</span><span id="line-2504"> put = new Put(row1);</span>
<span class="source-line-no">2505</span><span id="line-2505"> put.addColumn(fam1, qf1, now + 2, Bytes.toBytes(bd1));</span>
<span class="source-line-no">2506</span><span id="line-2506"> region.put(put);</span>
<span class="source-line-no">2507</span><span id="line-2507"></span>
<span class="source-line-no">2508</span><span id="line-2508"> // checkAndPut with correct value</span>
<span class="source-line-no">2509</span><span id="line-2509"> res = region.checkAndMutate(CheckAndMutate.newBuilder(row1)</span>
<span class="source-line-no">2510</span><span id="line-2510"> .ifMatches(fam1, qf1, CompareOperator.EQUAL, Bytes.toBytes(bd1)).build(put));</span>
<span class="source-line-no">2511</span><span id="line-2511"> assertTrue("Second put", res.isSuccess());</span>
<span class="source-line-no">2512</span><span id="line-2512"> assertNull(res.getResult());</span>
<span class="source-line-no">2513</span><span id="line-2513"></span>
<span class="source-line-no">2514</span><span id="line-2514"> // checkAndDelete with correct value</span>
<span class="source-line-no">2515</span><span id="line-2515"> delete = new Delete(row1, now + 3);</span>
<span class="source-line-no">2516</span><span id="line-2516"> delete.addColumn(fam1, qf1);</span>
<span class="source-line-no">2517</span><span id="line-2517"> res = region.checkAndMutate(CheckAndMutate.newBuilder(row1)</span>
<span class="source-line-no">2518</span><span id="line-2518"> .ifMatches(fam1, qf1, CompareOperator.EQUAL, Bytes.toBytes(bd1)).build(delete));</span>
<span class="source-line-no">2519</span><span id="line-2519"> assertTrue("Second delete", res.isSuccess());</span>
<span class="source-line-no">2520</span><span id="line-2520"> assertNull(res.getResult());</span>
<span class="source-line-no">2521</span><span id="line-2521"> }</span>
<span class="source-line-no">2522</span><span id="line-2522"></span>
<span class="source-line-no">2523</span><span id="line-2523"> @Test</span>
<span class="source-line-no">2524</span><span id="line-2524"> public void testCheckAndMutateWithNonEqualCompareOp() throws IOException {</span>
<span class="source-line-no">2525</span><span id="line-2525"> byte[] row1 = Bytes.toBytes("row1");</span>
<span class="source-line-no">2526</span><span id="line-2526"> byte[] fam1 = Bytes.toBytes("fam1");</span>
<span class="source-line-no">2527</span><span id="line-2527"> byte[] qf1 = Bytes.toBytes("qualifier");</span>
<span class="source-line-no">2528</span><span id="line-2528"> byte[] val1 = Bytes.toBytes("value1");</span>
<span class="source-line-no">2529</span><span id="line-2529"> byte[] val2 = Bytes.toBytes("value2");</span>
<span class="source-line-no">2530</span><span id="line-2530"> byte[] val3 = Bytes.toBytes("value3");</span>
<span class="source-line-no">2531</span><span id="line-2531"> byte[] val4 = Bytes.toBytes("value4");</span>
<span class="source-line-no">2532</span><span id="line-2532"></span>
<span class="source-line-no">2533</span><span id="line-2533"> // Setting up region</span>
<span class="source-line-no">2534</span><span id="line-2534"> this.region = initHRegion(tableName, method, CONF, fam1);</span>
<span class="source-line-no">2535</span><span id="line-2535"> // Putting val3 in key</span>
<span class="source-line-no">2536</span><span id="line-2536"> Put put = new Put(row1);</span>
<span class="source-line-no">2537</span><span id="line-2537"> put.addColumn(fam1, qf1, val3);</span>
<span class="source-line-no">2538</span><span id="line-2538"> region.put(put);</span>
<span class="source-line-no">2539</span><span id="line-2539"></span>
<span class="source-line-no">2540</span><span id="line-2540"> // Test CompareOp.LESS: original = val3, compare with val3, fail</span>
<span class="source-line-no">2541</span><span id="line-2541"> CheckAndMutateResult res = region.checkAndMutate(</span>
<span class="source-line-no">2542</span><span id="line-2542"> CheckAndMutate.newBuilder(row1).ifMatches(fam1, qf1, CompareOperator.LESS, val3).build(put));</span>
<span class="source-line-no">2543</span><span id="line-2543"> assertFalse(res.isSuccess());</span>
<span class="source-line-no">2544</span><span id="line-2544"> assertNull(res.getResult());</span>
<span class="source-line-no">2545</span><span id="line-2545"></span>
<span class="source-line-no">2546</span><span id="line-2546"> // Test CompareOp.LESS: original = val3, compare with val4, fail</span>
<span class="source-line-no">2547</span><span id="line-2547"> res = region.checkAndMutate(</span>
<span class="source-line-no">2548</span><span id="line-2548"> CheckAndMutate.newBuilder(row1).ifMatches(fam1, qf1, CompareOperator.LESS, val4).build(put));</span>
<span class="source-line-no">2549</span><span id="line-2549"> assertFalse(res.isSuccess());</span>
<span class="source-line-no">2550</span><span id="line-2550"> assertNull(res.getResult());</span>
<span class="source-line-no">2551</span><span id="line-2551"></span>
<span class="source-line-no">2552</span><span id="line-2552"> // Test CompareOp.LESS: original = val3, compare with val2,</span>
<span class="source-line-no">2553</span><span id="line-2553"> // succeed (now value = val2)</span>
<span class="source-line-no">2554</span><span id="line-2554"> put = new Put(row1);</span>
<span class="source-line-no">2555</span><span id="line-2555"> put.addColumn(fam1, qf1, val2);</span>
<span class="source-line-no">2556</span><span id="line-2556"> res = region.checkAndMutate(</span>
<span class="source-line-no">2557</span><span id="line-2557"> CheckAndMutate.newBuilder(row1).ifMatches(fam1, qf1, CompareOperator.LESS, val2).build(put));</span>
<span class="source-line-no">2558</span><span id="line-2558"> assertTrue(res.isSuccess());</span>
<span class="source-line-no">2559</span><span id="line-2559"> assertNull(res.getResult());</span>
<span class="source-line-no">2560</span><span id="line-2560"></span>
<span class="source-line-no">2561</span><span id="line-2561"> // Test CompareOp.LESS_OR_EQUAL: original = val2, compare with val3, fail</span>
<span class="source-line-no">2562</span><span id="line-2562"> res = region.checkAndMutate(CheckAndMutate.newBuilder(row1)</span>
<span class="source-line-no">2563</span><span id="line-2563"> .ifMatches(fam1, qf1, CompareOperator.LESS_OR_EQUAL, val3).build(put));</span>
<span class="source-line-no">2564</span><span id="line-2564"> assertFalse(res.isSuccess());</span>
<span class="source-line-no">2565</span><span id="line-2565"> assertNull(res.getResult());</span>
<span class="source-line-no">2566</span><span id="line-2566"></span>
<span class="source-line-no">2567</span><span id="line-2567"> // Test CompareOp.LESS_OR_EQUAL: original = val2, compare with val2,</span>
<span class="source-line-no">2568</span><span id="line-2568"> // succeed (value still = val2)</span>
<span class="source-line-no">2569</span><span id="line-2569"> res = region.checkAndMutate(CheckAndMutate.newBuilder(row1)</span>
<span class="source-line-no">2570</span><span id="line-2570"> .ifMatches(fam1, qf1, CompareOperator.LESS_OR_EQUAL, val2).build(put));</span>
<span class="source-line-no">2571</span><span id="line-2571"> assertTrue(res.isSuccess());</span>
<span class="source-line-no">2572</span><span id="line-2572"> assertNull(res.getResult());</span>
<span class="source-line-no">2573</span><span id="line-2573"></span>
<span class="source-line-no">2574</span><span id="line-2574"> // Test CompareOp.LESS_OR_EQUAL: original = val2, compare with val1,</span>
<span class="source-line-no">2575</span><span id="line-2575"> // succeed (now value = val3)</span>
<span class="source-line-no">2576</span><span id="line-2576"> put = new Put(row1);</span>
<span class="source-line-no">2577</span><span id="line-2577"> put.addColumn(fam1, qf1, val3);</span>
<span class="source-line-no">2578</span><span id="line-2578"> res = region.checkAndMutate(CheckAndMutate.newBuilder(row1)</span>
<span class="source-line-no">2579</span><span id="line-2579"> .ifMatches(fam1, qf1, CompareOperator.LESS_OR_EQUAL, val1).build(put));</span>
<span class="source-line-no">2580</span><span id="line-2580"> assertTrue(res.isSuccess());</span>
<span class="source-line-no">2581</span><span id="line-2581"> assertNull(res.getResult());</span>
<span class="source-line-no">2582</span><span id="line-2582"></span>
<span class="source-line-no">2583</span><span id="line-2583"> // Test CompareOp.GREATER: original = val3, compare with val3, fail</span>
<span class="source-line-no">2584</span><span id="line-2584"> res = region.checkAndMutate(CheckAndMutate.newBuilder(row1)</span>
<span class="source-line-no">2585</span><span id="line-2585"> .ifMatches(fam1, qf1, CompareOperator.GREATER, val3).build(put));</span>
<span class="source-line-no">2586</span><span id="line-2586"> assertFalse(res.isSuccess());</span>
<span class="source-line-no">2587</span><span id="line-2587"> assertNull(res.getResult());</span>
<span class="source-line-no">2588</span><span id="line-2588"></span>
<span class="source-line-no">2589</span><span id="line-2589"> // Test CompareOp.GREATER: original = val3, compare with val2, fail</span>
<span class="source-line-no">2590</span><span id="line-2590"> res = region.checkAndMutate(CheckAndMutate.newBuilder(row1)</span>
<span class="source-line-no">2591</span><span id="line-2591"> .ifMatches(fam1, qf1, CompareOperator.GREATER, val2).build(put));</span>
<span class="source-line-no">2592</span><span id="line-2592"> assertFalse(res.isSuccess());</span>
<span class="source-line-no">2593</span><span id="line-2593"> assertNull(res.getResult());</span>
<span class="source-line-no">2594</span><span id="line-2594"></span>
<span class="source-line-no">2595</span><span id="line-2595"> // Test CompareOp.GREATER: original = val3, compare with val4,</span>
<span class="source-line-no">2596</span><span id="line-2596"> // succeed (now value = val2)</span>
<span class="source-line-no">2597</span><span id="line-2597"> put = new Put(row1);</span>
<span class="source-line-no">2598</span><span id="line-2598"> put.addColumn(fam1, qf1, val2);</span>
<span class="source-line-no">2599</span><span id="line-2599"> res = region.checkAndMutate(CheckAndMutate.newBuilder(row1)</span>
<span class="source-line-no">2600</span><span id="line-2600"> .ifMatches(fam1, qf1, CompareOperator.GREATER, val4).build(put));</span>
<span class="source-line-no">2601</span><span id="line-2601"> assertTrue(res.isSuccess());</span>
<span class="source-line-no">2602</span><span id="line-2602"> assertNull(res.getResult());</span>
<span class="source-line-no">2603</span><span id="line-2603"></span>
<span class="source-line-no">2604</span><span id="line-2604"> // Test CompareOp.GREATER_OR_EQUAL: original = val2, compare with val1, fail</span>
<span class="source-line-no">2605</span><span id="line-2605"> res = region.checkAndMutate(CheckAndMutate.newBuilder(row1)</span>
<span class="source-line-no">2606</span><span id="line-2606"> .ifMatches(fam1, qf1, CompareOperator.GREATER_OR_EQUAL, val1).build(put));</span>
<span class="source-line-no">2607</span><span id="line-2607"> assertFalse(res.isSuccess());</span>
<span class="source-line-no">2608</span><span id="line-2608"> assertNull(res.getResult());</span>
<span class="source-line-no">2609</span><span id="line-2609"></span>
<span class="source-line-no">2610</span><span id="line-2610"> // Test CompareOp.GREATER_OR_EQUAL: original = val2, compare with val2,</span>
<span class="source-line-no">2611</span><span id="line-2611"> // succeed (value still = val2)</span>
<span class="source-line-no">2612</span><span id="line-2612"> res = region.checkAndMutate(CheckAndMutate.newBuilder(row1)</span>
<span class="source-line-no">2613</span><span id="line-2613"> .ifMatches(fam1, qf1, CompareOperator.GREATER_OR_EQUAL, val2).build(put));</span>
<span class="source-line-no">2614</span><span id="line-2614"> assertTrue(res.isSuccess());</span>
<span class="source-line-no">2615</span><span id="line-2615"> assertNull(res.getResult());</span>
<span class="source-line-no">2616</span><span id="line-2616"></span>
<span class="source-line-no">2617</span><span id="line-2617"> // Test CompareOp.GREATER_OR_EQUAL: original = val2, compare with val3, succeed</span>
<span class="source-line-no">2618</span><span id="line-2618"> res = region.checkAndMutate(CheckAndMutate.newBuilder(row1)</span>
<span class="source-line-no">2619</span><span id="line-2619"> .ifMatches(fam1, qf1, CompareOperator.GREATER_OR_EQUAL, val3).build(put));</span>
<span class="source-line-no">2620</span><span id="line-2620"> assertTrue(res.isSuccess());</span>
<span class="source-line-no">2621</span><span id="line-2621"> assertNull(res.getResult());</span>
<span class="source-line-no">2622</span><span id="line-2622"> }</span>
<span class="source-line-no">2623</span><span id="line-2623"></span>
<span class="source-line-no">2624</span><span id="line-2624"> @Test</span>
<span class="source-line-no">2625</span><span id="line-2625"> public void testCheckAndPutThatPutWasWritten() throws IOException {</span>
<span class="source-line-no">2626</span><span id="line-2626"> byte[] row1 = Bytes.toBytes("row1");</span>
<span class="source-line-no">2627</span><span id="line-2627"> byte[] fam1 = Bytes.toBytes("fam1");</span>
<span class="source-line-no">2628</span><span id="line-2628"> byte[] fam2 = Bytes.toBytes("fam2");</span>
<span class="source-line-no">2629</span><span id="line-2629"> byte[] qf1 = Bytes.toBytes("qualifier");</span>
<span class="source-line-no">2630</span><span id="line-2630"> byte[] val1 = Bytes.toBytes("value1");</span>
<span class="source-line-no">2631</span><span id="line-2631"> byte[] val2 = Bytes.toBytes("value2");</span>
<span class="source-line-no">2632</span><span id="line-2632"></span>
<span class="source-line-no">2633</span><span id="line-2633"> byte[][] families = { fam1, fam2 };</span>
<span class="source-line-no">2634</span><span id="line-2634"></span>
<span class="source-line-no">2635</span><span id="line-2635"> // Setting up region</span>
<span class="source-line-no">2636</span><span id="line-2636"> this.region = initHRegion(tableName, method, CONF, families);</span>
<span class="source-line-no">2637</span><span id="line-2637"> // Putting data in the key to check</span>
<span class="source-line-no">2638</span><span id="line-2638"> Put put = new Put(row1);</span>
<span class="source-line-no">2639</span><span id="line-2639"> put.addColumn(fam1, qf1, val1);</span>
<span class="source-line-no">2640</span><span id="line-2640"> region.put(put);</span>
<span class="source-line-no">2641</span><span id="line-2641"></span>
<span class="source-line-no">2642</span><span id="line-2642"> // Creating put to add</span>
<span class="source-line-no">2643</span><span id="line-2643"> long ts = EnvironmentEdgeManager.currentTime();</span>
<span class="source-line-no">2644</span><span id="line-2644"> KeyValue kv = new KeyValue(row1, fam2, qf1, ts, KeyValue.Type.Put, val2);</span>
<span class="source-line-no">2645</span><span id="line-2645"> put = new Put(row1);</span>
<span class="source-line-no">2646</span><span id="line-2646"> put.add(kv);</span>
<span class="source-line-no">2647</span><span id="line-2647"></span>
<span class="source-line-no">2648</span><span id="line-2648"> // checkAndPut with wrong value</span>
<span class="source-line-no">2649</span><span id="line-2649"> CheckAndMutateResult res = region.checkAndMutate(</span>
<span class="source-line-no">2650</span><span id="line-2650"> CheckAndMutate.newBuilder(row1).ifMatches(fam1, qf1, CompareOperator.EQUAL, val1).build(put));</span>
<span class="source-line-no">2651</span><span id="line-2651"> assertTrue(res.isSuccess());</span>
<span class="source-line-no">2652</span><span id="line-2652"> assertNull(res.getResult());</span>
<span class="source-line-no">2653</span><span id="line-2653"></span>
<span class="source-line-no">2654</span><span id="line-2654"> Get get = new Get(row1);</span>
<span class="source-line-no">2655</span><span id="line-2655"> get.addColumn(fam2, qf1);</span>
<span class="source-line-no">2656</span><span id="line-2656"> Cell[] actual = region.get(get).rawCells();</span>
<span class="source-line-no">2657</span><span id="line-2657"></span>
<span class="source-line-no">2658</span><span id="line-2658"> Cell[] expected = { kv };</span>
<span class="source-line-no">2659</span><span id="line-2659"></span>
<span class="source-line-no">2660</span><span id="line-2660"> assertEquals(expected.length, actual.length);</span>
<span class="source-line-no">2661</span><span id="line-2661"> for (int i = 0; i &lt; actual.length; i++) {</span>
<span class="source-line-no">2662</span><span id="line-2662"> assertEquals(expected[i], actual[i]);</span>
<span class="source-line-no">2663</span><span id="line-2663"> }</span>
<span class="source-line-no">2664</span><span id="line-2664"> }</span>
<span class="source-line-no">2665</span><span id="line-2665"></span>
<span class="source-line-no">2666</span><span id="line-2666"> @Test</span>
<span class="source-line-no">2667</span><span id="line-2667"> public void testCheckAndDeleteThatDeleteWasWritten() throws IOException {</span>
<span class="source-line-no">2668</span><span id="line-2668"> byte[] row1 = Bytes.toBytes("row1");</span>
<span class="source-line-no">2669</span><span id="line-2669"> byte[] fam1 = Bytes.toBytes("fam1");</span>
<span class="source-line-no">2670</span><span id="line-2670"> byte[] fam2 = Bytes.toBytes("fam2");</span>
<span class="source-line-no">2671</span><span id="line-2671"> byte[] qf1 = Bytes.toBytes("qualifier1");</span>
<span class="source-line-no">2672</span><span id="line-2672"> byte[] qf2 = Bytes.toBytes("qualifier2");</span>
<span class="source-line-no">2673</span><span id="line-2673"> byte[] qf3 = Bytes.toBytes("qualifier3");</span>
<span class="source-line-no">2674</span><span id="line-2674"> byte[] val1 = Bytes.toBytes("value1");</span>
<span class="source-line-no">2675</span><span id="line-2675"> byte[] val2 = Bytes.toBytes("value2");</span>
<span class="source-line-no">2676</span><span id="line-2676"> byte[] val3 = Bytes.toBytes("value3");</span>
<span class="source-line-no">2677</span><span id="line-2677"> byte[] emptyVal = new byte[] {};</span>
<span class="source-line-no">2678</span><span id="line-2678"></span>
<span class="source-line-no">2679</span><span id="line-2679"> byte[][] families = { fam1, fam2 };</span>
<span class="source-line-no">2680</span><span id="line-2680"></span>
<span class="source-line-no">2681</span><span id="line-2681"> // Setting up region</span>
<span class="source-line-no">2682</span><span id="line-2682"> this.region = initHRegion(tableName, method, CONF, families);</span>
<span class="source-line-no">2683</span><span id="line-2683"> // Put content</span>
<span class="source-line-no">2684</span><span id="line-2684"> Put put = new Put(row1);</span>
<span class="source-line-no">2685</span><span id="line-2685"> put.addColumn(fam1, qf1, val1);</span>
<span class="source-line-no">2686</span><span id="line-2686"> region.put(put);</span>
<span class="source-line-no">2687</span><span id="line-2687"> Threads.sleep(2);</span>
<span class="source-line-no">2688</span><span id="line-2688"></span>
<span class="source-line-no">2689</span><span id="line-2689"> put = new Put(row1);</span>
<span class="source-line-no">2690</span><span id="line-2690"> put.addColumn(fam1, qf1, val2);</span>
<span class="source-line-no">2691</span><span id="line-2691"> put.addColumn(fam2, qf1, val3);</span>
<span class="source-line-no">2692</span><span id="line-2692"> put.addColumn(fam2, qf2, val2);</span>
<span class="source-line-no">2693</span><span id="line-2693"> put.addColumn(fam2, qf3, val1);</span>
<span class="source-line-no">2694</span><span id="line-2694"> put.addColumn(fam1, qf3, val1);</span>
<span class="source-line-no">2695</span><span id="line-2695"> region.put(put);</span>
<span class="source-line-no">2696</span><span id="line-2696"></span>
<span class="source-line-no">2697</span><span id="line-2697"> LOG.info("get={}", region.get(new Get(row1).addColumn(fam1, qf1)).toString());</span>
<span class="source-line-no">2698</span><span id="line-2698"></span>
<span class="source-line-no">2699</span><span id="line-2699"> // Multi-column delete</span>
<span class="source-line-no">2700</span><span id="line-2700"> Delete delete = new Delete(row1);</span>
<span class="source-line-no">2701</span><span id="line-2701"> delete.addColumn(fam1, qf1);</span>
<span class="source-line-no">2702</span><span id="line-2702"> delete.addColumn(fam2, qf1);</span>
<span class="source-line-no">2703</span><span id="line-2703"> delete.addColumn(fam1, qf3);</span>
<span class="source-line-no">2704</span><span id="line-2704"> CheckAndMutateResult res = region.checkAndMutate(CheckAndMutate.newBuilder(row1)</span>
<span class="source-line-no">2705</span><span id="line-2705"> .ifMatches(fam1, qf1, CompareOperator.EQUAL, val2).build(delete));</span>
<span class="source-line-no">2706</span><span id="line-2706"> assertTrue(res.isSuccess());</span>
<span class="source-line-no">2707</span><span id="line-2707"> assertNull(res.getResult());</span>
<span class="source-line-no">2708</span><span id="line-2708"></span>
<span class="source-line-no">2709</span><span id="line-2709"> Get get = new Get(row1);</span>
<span class="source-line-no">2710</span><span id="line-2710"> get.addColumn(fam1, qf1);</span>
<span class="source-line-no">2711</span><span id="line-2711"> get.addColumn(fam1, qf3);</span>
<span class="source-line-no">2712</span><span id="line-2712"> get.addColumn(fam2, qf2);</span>
<span class="source-line-no">2713</span><span id="line-2713"> Result r = region.get(get);</span>
<span class="source-line-no">2714</span><span id="line-2714"> assertEquals(2, r.size());</span>
<span class="source-line-no">2715</span><span id="line-2715"> assertArrayEquals(val1, r.getValue(fam1, qf1));</span>
<span class="source-line-no">2716</span><span id="line-2716"> assertArrayEquals(val2, r.getValue(fam2, qf2));</span>
<span class="source-line-no">2717</span><span id="line-2717"></span>
<span class="source-line-no">2718</span><span id="line-2718"> // Family delete</span>
<span class="source-line-no">2719</span><span id="line-2719"> delete = new Delete(row1);</span>
<span class="source-line-no">2720</span><span id="line-2720"> delete.addFamily(fam2);</span>
<span class="source-line-no">2721</span><span id="line-2721"> res = region.checkAndMutate(CheckAndMutate.newBuilder(row1)</span>
<span class="source-line-no">2722</span><span id="line-2722"> .ifMatches(fam2, qf1, CompareOperator.EQUAL, emptyVal).build(delete));</span>
<span class="source-line-no">2723</span><span id="line-2723"> assertTrue(res.isSuccess());</span>
<span class="source-line-no">2724</span><span id="line-2724"> assertNull(res.getResult());</span>
<span class="source-line-no">2725</span><span id="line-2725"></span>
<span class="source-line-no">2726</span><span id="line-2726"> get = new Get(row1);</span>
<span class="source-line-no">2727</span><span id="line-2727"> r = region.get(get);</span>
<span class="source-line-no">2728</span><span id="line-2728"> assertEquals(1, r.size());</span>
<span class="source-line-no">2729</span><span id="line-2729"> assertArrayEquals(val1, r.getValue(fam1, qf1));</span>
<span class="source-line-no">2730</span><span id="line-2730"></span>
<span class="source-line-no">2731</span><span id="line-2731"> // Row delete</span>
<span class="source-line-no">2732</span><span id="line-2732"> delete = new Delete(row1);</span>
<span class="source-line-no">2733</span><span id="line-2733"> res = region.checkAndMutate(CheckAndMutate.newBuilder(row1)</span>
<span class="source-line-no">2734</span><span id="line-2734"> .ifMatches(fam1, qf1, CompareOperator.EQUAL, val1).build(delete));</span>
<span class="source-line-no">2735</span><span id="line-2735"> assertTrue(res.isSuccess());</span>
<span class="source-line-no">2736</span><span id="line-2736"> assertNull(res.getResult());</span>
<span class="source-line-no">2737</span><span id="line-2737"></span>
<span class="source-line-no">2738</span><span id="line-2738"> get = new Get(row1);</span>
<span class="source-line-no">2739</span><span id="line-2739"> r = region.get(get);</span>
<span class="source-line-no">2740</span><span id="line-2740"> assertEquals(0, r.size());</span>
<span class="source-line-no">2741</span><span id="line-2741"> }</span>
<span class="source-line-no">2742</span><span id="line-2742"></span>
<span class="source-line-no">2743</span><span id="line-2743"> @Test</span>
<span class="source-line-no">2744</span><span id="line-2744"> public void testCheckAndMutateWithFilters() throws Throwable {</span>
<span class="source-line-no">2745</span><span id="line-2745"> final byte[] FAMILY = Bytes.toBytes("fam");</span>
<span class="source-line-no">2746</span><span id="line-2746"></span>
<span class="source-line-no">2747</span><span id="line-2747"> // Setting up region</span>
<span class="source-line-no">2748</span><span id="line-2748"> this.region = initHRegion(tableName, method, CONF, FAMILY);</span>
<span class="source-line-no">2749</span><span id="line-2749"></span>
<span class="source-line-no">2750</span><span id="line-2750"> // Put one row</span>
<span class="source-line-no">2751</span><span id="line-2751"> Put put = new Put(row);</span>
<span class="source-line-no">2752</span><span id="line-2752"> put.addColumn(FAMILY, Bytes.toBytes("A"), Bytes.toBytes("a"));</span>
<span class="source-line-no">2753</span><span id="line-2753"> put.addColumn(FAMILY, Bytes.toBytes("B"), Bytes.toBytes("b"));</span>
<span class="source-line-no">2754</span><span id="line-2754"> put.addColumn(FAMILY, Bytes.toBytes("C"), Bytes.toBytes("c"));</span>
<span class="source-line-no">2755</span><span id="line-2755"> region.put(put);</span>
<span class="source-line-no">2756</span><span id="line-2756"></span>
<span class="source-line-no">2757</span><span id="line-2757"> // Put with success</span>
<span class="source-line-no">2758</span><span id="line-2758"> CheckAndMutateResult res = region.checkAndMutate(CheckAndMutate.newBuilder(row)</span>
<span class="source-line-no">2759</span><span id="line-2759"> .ifMatches(new FilterList(</span>
<span class="source-line-no">2760</span><span id="line-2760"> new SingleColumnValueFilter(FAMILY, Bytes.toBytes("A"), CompareOperator.EQUAL,</span>
<span class="source-line-no">2761</span><span id="line-2761"> Bytes.toBytes("a")),</span>
<span class="source-line-no">2762</span><span id="line-2762"> new SingleColumnValueFilter(FAMILY, Bytes.toBytes("B"), CompareOperator.EQUAL,</span>
<span class="source-line-no">2763</span><span id="line-2763"> Bytes.toBytes("b"))))</span>
<span class="source-line-no">2764</span><span id="line-2764"> .build(new Put(row).addColumn(FAMILY, Bytes.toBytes("D"), Bytes.toBytes("d"))));</span>
<span class="source-line-no">2765</span><span id="line-2765"> assertTrue(res.isSuccess());</span>
<span class="source-line-no">2766</span><span id="line-2766"> assertNull(res.getResult());</span>
<span class="source-line-no">2767</span><span id="line-2767"></span>
<span class="source-line-no">2768</span><span id="line-2768"> Result result = region.get(new Get(row).addColumn(FAMILY, Bytes.toBytes("D")));</span>
<span class="source-line-no">2769</span><span id="line-2769"> assertEquals("d", Bytes.toString(result.getValue(FAMILY, Bytes.toBytes("D"))));</span>
<span class="source-line-no">2770</span><span id="line-2770"></span>
<span class="source-line-no">2771</span><span id="line-2771"> // Put with failure</span>
<span class="source-line-no">2772</span><span id="line-2772"> res = region.checkAndMutate(CheckAndMutate.newBuilder(row)</span>
<span class="source-line-no">2773</span><span id="line-2773"> .ifMatches(new FilterList(</span>
<span class="source-line-no">2774</span><span id="line-2774"> new SingleColumnValueFilter(FAMILY, Bytes.toBytes("A"), CompareOperator.EQUAL,</span>
<span class="source-line-no">2775</span><span id="line-2775"> Bytes.toBytes("a")),</span>
<span class="source-line-no">2776</span><span id="line-2776"> new SingleColumnValueFilter(FAMILY, Bytes.toBytes("B"), CompareOperator.EQUAL,</span>
<span class="source-line-no">2777</span><span id="line-2777"> Bytes.toBytes("c"))))</span>
<span class="source-line-no">2778</span><span id="line-2778"> .build(new Put(row).addColumn(FAMILY, Bytes.toBytes("E"), Bytes.toBytes("e"))));</span>
<span class="source-line-no">2779</span><span id="line-2779"> assertFalse(res.isSuccess());</span>
<span class="source-line-no">2780</span><span id="line-2780"> assertNull(res.getResult());</span>
<span class="source-line-no">2781</span><span id="line-2781"></span>
<span class="source-line-no">2782</span><span id="line-2782"> assertTrue(region.get(new Get(row).addColumn(FAMILY, Bytes.toBytes("E"))).isEmpty());</span>
<span class="source-line-no">2783</span><span id="line-2783"></span>
<span class="source-line-no">2784</span><span id="line-2784"> // Delete with success</span>
<span class="source-line-no">2785</span><span id="line-2785"> res = region.checkAndMutate(CheckAndMutate.newBuilder(row)</span>
<span class="source-line-no">2786</span><span id="line-2786"> .ifMatches(new FilterList(</span>
<span class="source-line-no">2787</span><span id="line-2787"> new SingleColumnValueFilter(FAMILY, Bytes.toBytes("A"), CompareOperator.EQUAL,</span>
<span class="source-line-no">2788</span><span id="line-2788"> Bytes.toBytes("a")),</span>
<span class="source-line-no">2789</span><span id="line-2789"> new SingleColumnValueFilter(FAMILY, Bytes.toBytes("B"), CompareOperator.EQUAL,</span>
<span class="source-line-no">2790</span><span id="line-2790"> Bytes.toBytes("b"))))</span>
<span class="source-line-no">2791</span><span id="line-2791"> .build(new Delete(row).addColumns(FAMILY, Bytes.toBytes("D"))));</span>
<span class="source-line-no">2792</span><span id="line-2792"> assertTrue(res.isSuccess());</span>
<span class="source-line-no">2793</span><span id="line-2793"> assertNull(res.getResult());</span>
<span class="source-line-no">2794</span><span id="line-2794"></span>
<span class="source-line-no">2795</span><span id="line-2795"> assertTrue(region.get(new Get(row).addColumn(FAMILY, Bytes.toBytes("D"))).isEmpty());</span>
<span class="source-line-no">2796</span><span id="line-2796"></span>
<span class="source-line-no">2797</span><span id="line-2797"> // Mutate with success</span>
<span class="source-line-no">2798</span><span id="line-2798"> res = region.checkAndMutate(CheckAndMutate.newBuilder(row)</span>
<span class="source-line-no">2799</span><span id="line-2799"> .ifMatches(new FilterList(</span>
<span class="source-line-no">2800</span><span id="line-2800"> new SingleColumnValueFilter(FAMILY, Bytes.toBytes("A"), CompareOperator.EQUAL,</span>
<span class="source-line-no">2801</span><span id="line-2801"> Bytes.toBytes("a")),</span>
<span class="source-line-no">2802</span><span id="line-2802"> new SingleColumnValueFilter(FAMILY, Bytes.toBytes("B"), CompareOperator.EQUAL,</span>
<span class="source-line-no">2803</span><span id="line-2803"> Bytes.toBytes("b"))))</span>
<span class="source-line-no">2804</span><span id="line-2804"> .build(new RowMutations(row)</span>
<span class="source-line-no">2805</span><span id="line-2805"> .add((Mutation) new Put(row).addColumn(FAMILY, Bytes.toBytes("E"), Bytes.toBytes("e")))</span>
<span class="source-line-no">2806</span><span id="line-2806"> .add((Mutation) new Delete(row).addColumns(FAMILY, Bytes.toBytes("A")))));</span>
<span class="source-line-no">2807</span><span id="line-2807"> assertTrue(res.isSuccess());</span>
<span class="source-line-no">2808</span><span id="line-2808"> assertNull(res.getResult());</span>
<span class="source-line-no">2809</span><span id="line-2809"></span>
<span class="source-line-no">2810</span><span id="line-2810"> result = region.get(new Get(row).addColumn(FAMILY, Bytes.toBytes("E")));</span>
<span class="source-line-no">2811</span><span id="line-2811"> assertEquals("e", Bytes.toString(result.getValue(FAMILY, Bytes.toBytes("E"))));</span>
<span class="source-line-no">2812</span><span id="line-2812"></span>
<span class="source-line-no">2813</span><span id="line-2813"> assertTrue(region.get(new Get(row).addColumn(FAMILY, Bytes.toBytes("A"))).isEmpty());</span>
<span class="source-line-no">2814</span><span id="line-2814"> }</span>
<span class="source-line-no">2815</span><span id="line-2815"></span>
<span class="source-line-no">2816</span><span id="line-2816"> @Test</span>
<span class="source-line-no">2817</span><span id="line-2817"> public void testCheckAndMutateWithFiltersAndTimeRange() throws Throwable {</span>
<span class="source-line-no">2818</span><span id="line-2818"> final byte[] FAMILY = Bytes.toBytes("fam");</span>
<span class="source-line-no">2819</span><span id="line-2819"></span>
<span class="source-line-no">2820</span><span id="line-2820"> // Setting up region</span>
<span class="source-line-no">2821</span><span id="line-2821"> this.region = initHRegion(tableName, method, CONF, FAMILY);</span>
<span class="source-line-no">2822</span><span id="line-2822"></span>
<span class="source-line-no">2823</span><span id="line-2823"> // Put with specifying the timestamp</span>
<span class="source-line-no">2824</span><span id="line-2824"> region.put(new Put(row).addColumn(FAMILY, Bytes.toBytes("A"), 100, Bytes.toBytes("a")));</span>
<span class="source-line-no">2825</span><span id="line-2825"></span>
<span class="source-line-no">2826</span><span id="line-2826"> // Put with success</span>
<span class="source-line-no">2827</span><span id="line-2827"> CheckAndMutateResult res = region.checkAndMutate(CheckAndMutate.newBuilder(row)</span>
<span class="source-line-no">2828</span><span id="line-2828"> .ifMatches(new SingleColumnValueFilter(FAMILY, Bytes.toBytes("A"), CompareOperator.EQUAL,</span>
<span class="source-line-no">2829</span><span id="line-2829"> Bytes.toBytes("a")))</span>
<span class="source-line-no">2830</span><span id="line-2830"> .timeRange(TimeRange.between(0, 101))</span>
<span class="source-line-no">2831</span><span id="line-2831"> .build(new Put(row).addColumn(FAMILY, Bytes.toBytes("B"), Bytes.toBytes("b"))));</span>
<span class="source-line-no">2832</span><span id="line-2832"> assertTrue(res.isSuccess());</span>
<span class="source-line-no">2833</span><span id="line-2833"> assertNull(res.getResult());</span>
<span class="source-line-no">2834</span><span id="line-2834"></span>
<span class="source-line-no">2835</span><span id="line-2835"> Result result = region.get(new Get(row).addColumn(FAMILY, Bytes.toBytes("B")));</span>
<span class="source-line-no">2836</span><span id="line-2836"> assertEquals("b", Bytes.toString(result.getValue(FAMILY, Bytes.toBytes("B"))));</span>
<span class="source-line-no">2837</span><span id="line-2837"></span>
<span class="source-line-no">2838</span><span id="line-2838"> // Put with failure</span>
<span class="source-line-no">2839</span><span id="line-2839"> res = region.checkAndMutate(CheckAndMutate.newBuilder(row)</span>
<span class="source-line-no">2840</span><span id="line-2840"> .ifMatches(new SingleColumnValueFilter(FAMILY, Bytes.toBytes("A"), CompareOperator.EQUAL,</span>
<span class="source-line-no">2841</span><span id="line-2841"> Bytes.toBytes("a")))</span>
<span class="source-line-no">2842</span><span id="line-2842"> .timeRange(TimeRange.between(0, 100))</span>
<span class="source-line-no">2843</span><span id="line-2843"> .build(new Put(row).addColumn(FAMILY, Bytes.toBytes("C"), Bytes.toBytes("c"))));</span>
<span class="source-line-no">2844</span><span id="line-2844"> assertFalse(res.isSuccess());</span>
<span class="source-line-no">2845</span><span id="line-2845"> assertNull(res.getResult());</span>
<span class="source-line-no">2846</span><span id="line-2846"></span>
<span class="source-line-no">2847</span><span id="line-2847"> assertTrue(region.get(new Get(row).addColumn(FAMILY, Bytes.toBytes("C"))).isEmpty());</span>
<span class="source-line-no">2848</span><span id="line-2848"></span>
<span class="source-line-no">2849</span><span id="line-2849"> // RowMutations with success</span>
<span class="source-line-no">2850</span><span id="line-2850"> res = region.checkAndMutate(CheckAndMutate.newBuilder(row)</span>
<span class="source-line-no">2851</span><span id="line-2851"> .ifMatches(new SingleColumnValueFilter(FAMILY, Bytes.toBytes("A"), CompareOperator.EQUAL,</span>
<span class="source-line-no">2852</span><span id="line-2852"> Bytes.toBytes("a")))</span>
<span class="source-line-no">2853</span><span id="line-2853"> .timeRange(TimeRange.between(0, 101))</span>
<span class="source-line-no">2854</span><span id="line-2854"> .build(new RowMutations(row)</span>
<span class="source-line-no">2855</span><span id="line-2855"> .add((Mutation) new Put(row).addColumn(FAMILY, Bytes.toBytes("D"), Bytes.toBytes("d")))</span>
<span class="source-line-no">2856</span><span id="line-2856"> .add((Mutation) new Delete(row).addColumns(FAMILY, Bytes.toBytes("A")))));</span>
<span class="source-line-no">2857</span><span id="line-2857"> assertTrue(res.isSuccess());</span>
<span class="source-line-no">2858</span><span id="line-2858"> assertNull(res.getResult());</span>
<span class="source-line-no">2859</span><span id="line-2859"></span>
<span class="source-line-no">2860</span><span id="line-2860"> result = region.get(new Get(row).addColumn(FAMILY, Bytes.toBytes("D")));</span>
<span class="source-line-no">2861</span><span id="line-2861"> assertEquals("d", Bytes.toString(result.getValue(FAMILY, Bytes.toBytes("D"))));</span>
<span class="source-line-no">2862</span><span id="line-2862"></span>
<span class="source-line-no">2863</span><span id="line-2863"> assertTrue(region.get(new Get(row).addColumn(FAMILY, Bytes.toBytes("A"))).isEmpty());</span>
<span class="source-line-no">2864</span><span id="line-2864"> }</span>
<span class="source-line-no">2865</span><span id="line-2865"></span>
<span class="source-line-no">2866</span><span id="line-2866"> @Test</span>
<span class="source-line-no">2867</span><span id="line-2867"> public void testCheckAndIncrement() throws Throwable {</span>
<span class="source-line-no">2868</span><span id="line-2868"> final byte[] FAMILY = Bytes.toBytes("fam");</span>
<span class="source-line-no">2869</span><span id="line-2869"></span>
<span class="source-line-no">2870</span><span id="line-2870"> // Setting up region</span>
<span class="source-line-no">2871</span><span id="line-2871"> this.region = initHRegion(tableName, method, CONF, FAMILY);</span>
<span class="source-line-no">2872</span><span id="line-2872"></span>
<span class="source-line-no">2873</span><span id="line-2873"> region.put(new Put(row).addColumn(FAMILY, Bytes.toBytes("A"), Bytes.toBytes("a")));</span>
<span class="source-line-no">2874</span><span id="line-2874"></span>
<span class="source-line-no">2875</span><span id="line-2875"> // CheckAndIncrement with correct value</span>
<span class="source-line-no">2876</span><span id="line-2876"> CheckAndMutateResult res = region.checkAndMutate(</span>
<span class="source-line-no">2877</span><span id="line-2877"> CheckAndMutate.newBuilder(row).ifEquals(FAMILY, Bytes.toBytes("A"), Bytes.toBytes("a"))</span>
<span class="source-line-no">2878</span><span id="line-2878"> .build(new Increment(row).addColumn(FAMILY, Bytes.toBytes("B"), 1)));</span>
<span class="source-line-no">2879</span><span id="line-2879"> assertTrue(res.isSuccess());</span>
<span class="source-line-no">2880</span><span id="line-2880"> assertEquals(1, Bytes.toLong(res.getResult().getValue(FAMILY, Bytes.toBytes("B"))));</span>
<span class="source-line-no">2881</span><span id="line-2881"></span>
<span class="source-line-no">2882</span><span id="line-2882"> Result result = region.get(new Get(row).addColumn(FAMILY, Bytes.toBytes("B")));</span>
<span class="source-line-no">2883</span><span id="line-2883"> assertEquals(1, Bytes.toLong(result.getValue(FAMILY, Bytes.toBytes("B"))));</span>
<span class="source-line-no">2884</span><span id="line-2884"></span>
<span class="source-line-no">2885</span><span id="line-2885"> // CheckAndIncrement with wrong value</span>
<span class="source-line-no">2886</span><span id="line-2886"> res = region.checkAndMutate(</span>
<span class="source-line-no">2887</span><span id="line-2887"> CheckAndMutate.newBuilder(row).ifEquals(FAMILY, Bytes.toBytes("A"), Bytes.toBytes("b"))</span>
<span class="source-line-no">2888</span><span id="line-2888"> .build(new Increment(row).addColumn(FAMILY, Bytes.toBytes("B"), 1)));</span>
<span class="source-line-no">2889</span><span id="line-2889"> assertFalse(res.isSuccess());</span>
<span class="source-line-no">2890</span><span id="line-2890"> assertNull(res.getResult());</span>
<span class="source-line-no">2891</span><span id="line-2891"></span>
<span class="source-line-no">2892</span><span id="line-2892"> result = region.get(new Get(row).addColumn(FAMILY, Bytes.toBytes("B")));</span>
<span class="source-line-no">2893</span><span id="line-2893"> assertEquals(1, Bytes.toLong(result.getValue(FAMILY, Bytes.toBytes("B"))));</span>
<span class="source-line-no">2894</span><span id="line-2894"></span>
<span class="source-line-no">2895</span><span id="line-2895"> region.put(new Put(row).addColumn(FAMILY, Bytes.toBytes("C"), Bytes.toBytes("c")));</span>
<span class="source-line-no">2896</span><span id="line-2896"></span>
<span class="source-line-no">2897</span><span id="line-2897"> // CheckAndIncrement with a filter and correct value</span>
<span class="source-line-no">2898</span><span id="line-2898"> res = region.checkAndMutate(CheckAndMutate.newBuilder(row)</span>
<span class="source-line-no">2899</span><span id="line-2899"> .ifMatches(new FilterList(</span>
<span class="source-line-no">2900</span><span id="line-2900"> new SingleColumnValueFilter(FAMILY, Bytes.toBytes("A"), CompareOperator.EQUAL,</span>
<span class="source-line-no">2901</span><span id="line-2901"> Bytes.toBytes("a")),</span>
<span class="source-line-no">2902</span><span id="line-2902"> new SingleColumnValueFilter(FAMILY, Bytes.toBytes("C"), CompareOperator.EQUAL,</span>
<span class="source-line-no">2903</span><span id="line-2903"> Bytes.toBytes("c"))))</span>
<span class="source-line-no">2904</span><span id="line-2904"> .build(new Increment(row).addColumn(FAMILY, Bytes.toBytes("B"), 2)));</span>
<span class="source-line-no">2905</span><span id="line-2905"> assertTrue(res.isSuccess());</span>
<span class="source-line-no">2906</span><span id="line-2906"> assertEquals(3, Bytes.toLong(res.getResult().getValue(FAMILY, Bytes.toBytes("B"))));</span>
<span class="source-line-no">2907</span><span id="line-2907"></span>
<span class="source-line-no">2908</span><span id="line-2908"> result = region.get(new Get(row).addColumn(FAMILY, Bytes.toBytes("B")));</span>
<span class="source-line-no">2909</span><span id="line-2909"> assertEquals(3, Bytes.toLong(result.getValue(FAMILY, Bytes.toBytes("B"))));</span>
<span class="source-line-no">2910</span><span id="line-2910"></span>
<span class="source-line-no">2911</span><span id="line-2911"> // CheckAndIncrement with a filter and correct value</span>
<span class="source-line-no">2912</span><span id="line-2912"> res = region.checkAndMutate(CheckAndMutate.newBuilder(row)</span>
<span class="source-line-no">2913</span><span id="line-2913"> .ifMatches(new FilterList(</span>
<span class="source-line-no">2914</span><span id="line-2914"> new SingleColumnValueFilter(FAMILY, Bytes.toBytes("A"), CompareOperator.EQUAL,</span>
<span class="source-line-no">2915</span><span id="line-2915"> Bytes.toBytes("b")),</span>
<span class="source-line-no">2916</span><span id="line-2916"> new SingleColumnValueFilter(FAMILY, Bytes.toBytes("C"), CompareOperator.EQUAL,</span>
<span class="source-line-no">2917</span><span id="line-2917"> Bytes.toBytes("d"))))</span>
<span class="source-line-no">2918</span><span id="line-2918"> .build(new Increment(row).addColumn(FAMILY, Bytes.toBytes("B"), 2)));</span>
<span class="source-line-no">2919</span><span id="line-2919"> assertFalse(res.isSuccess());</span>
<span class="source-line-no">2920</span><span id="line-2920"> assertNull(res.getResult());</span>
<span class="source-line-no">2921</span><span id="line-2921"></span>
<span class="source-line-no">2922</span><span id="line-2922"> result = region.get(new Get(row).addColumn(FAMILY, Bytes.toBytes("B")));</span>
<span class="source-line-no">2923</span><span id="line-2923"> assertEquals(3, Bytes.toLong(result.getValue(FAMILY, Bytes.toBytes("B"))));</span>
<span class="source-line-no">2924</span><span id="line-2924"> }</span>
<span class="source-line-no">2925</span><span id="line-2925"></span>
<span class="source-line-no">2926</span><span id="line-2926"> @Test</span>
<span class="source-line-no">2927</span><span id="line-2927"> public void testCheckAndAppend() throws Throwable {</span>
<span class="source-line-no">2928</span><span id="line-2928"> final byte[] FAMILY = Bytes.toBytes("fam");</span>
<span class="source-line-no">2929</span><span id="line-2929"></span>
<span class="source-line-no">2930</span><span id="line-2930"> // Setting up region</span>
<span class="source-line-no">2931</span><span id="line-2931"> this.region = initHRegion(tableName, method, CONF, FAMILY);</span>
<span class="source-line-no">2932</span><span id="line-2932"></span>
<span class="source-line-no">2933</span><span id="line-2933"> region.put(new Put(row).addColumn(FAMILY, Bytes.toBytes("A"), Bytes.toBytes("a")));</span>
<span class="source-line-no">2934</span><span id="line-2934"></span>
<span class="source-line-no">2935</span><span id="line-2935"> // CheckAndAppend with correct value</span>
<span class="source-line-no">2936</span><span id="line-2936"> CheckAndMutateResult res = region.checkAndMutate(</span>
<span class="source-line-no">2937</span><span id="line-2937"> CheckAndMutate.newBuilder(row).ifEquals(FAMILY, Bytes.toBytes("A"), Bytes.toBytes("a"))</span>
<span class="source-line-no">2938</span><span id="line-2938"> .build(new Append(row).addColumn(FAMILY, Bytes.toBytes("B"), Bytes.toBytes("b"))));</span>
<span class="source-line-no">2939</span><span id="line-2939"> assertTrue(res.isSuccess());</span>
<span class="source-line-no">2940</span><span id="line-2940"> assertEquals("b", Bytes.toString(res.getResult().getValue(FAMILY, Bytes.toBytes("B"))));</span>
<span class="source-line-no">2941</span><span id="line-2941"></span>
<span class="source-line-no">2942</span><span id="line-2942"> Result result = region.get(new Get(row).addColumn(FAMILY, Bytes.toBytes("B")));</span>
<span class="source-line-no">2943</span><span id="line-2943"> assertEquals("b", Bytes.toString(result.getValue(FAMILY, Bytes.toBytes("B"))));</span>
<span class="source-line-no">2944</span><span id="line-2944"></span>
<span class="source-line-no">2945</span><span id="line-2945"> // CheckAndAppend with wrong value</span>
<span class="source-line-no">2946</span><span id="line-2946"> res = region.checkAndMutate(</span>
<span class="source-line-no">2947</span><span id="line-2947"> CheckAndMutate.newBuilder(row).ifEquals(FAMILY, Bytes.toBytes("A"), Bytes.toBytes("b"))</span>
<span class="source-line-no">2948</span><span id="line-2948"> .build(new Append(row).addColumn(FAMILY, Bytes.toBytes("B"), Bytes.toBytes("b"))));</span>
<span class="source-line-no">2949</span><span id="line-2949"> assertFalse(res.isSuccess());</span>
<span class="source-line-no">2950</span><span id="line-2950"> assertNull(res.getResult());</span>
<span class="source-line-no">2951</span><span id="line-2951"></span>
<span class="source-line-no">2952</span><span id="line-2952"> result = region.get(new Get(row).addColumn(FAMILY, Bytes.toBytes("B")));</span>
<span class="source-line-no">2953</span><span id="line-2953"> assertEquals("b", Bytes.toString(result.getValue(FAMILY, Bytes.toBytes("B"))));</span>
<span class="source-line-no">2954</span><span id="line-2954"></span>
<span class="source-line-no">2955</span><span id="line-2955"> region.put(new Put(row).addColumn(FAMILY, Bytes.toBytes("C"), Bytes.toBytes("c")));</span>
<span class="source-line-no">2956</span><span id="line-2956"></span>
<span class="source-line-no">2957</span><span id="line-2957"> // CheckAndAppend with a filter and correct value</span>
<span class="source-line-no">2958</span><span id="line-2958"> res = region.checkAndMutate(CheckAndMutate.newBuilder(row)</span>
<span class="source-line-no">2959</span><span id="line-2959"> .ifMatches(new FilterList(</span>
<span class="source-line-no">2960</span><span id="line-2960"> new SingleColumnValueFilter(FAMILY, Bytes.toBytes("A"), CompareOperator.EQUAL,</span>
<span class="source-line-no">2961</span><span id="line-2961"> Bytes.toBytes("a")),</span>
<span class="source-line-no">2962</span><span id="line-2962"> new SingleColumnValueFilter(FAMILY, Bytes.toBytes("C"), CompareOperator.EQUAL,</span>
<span class="source-line-no">2963</span><span id="line-2963"> Bytes.toBytes("c"))))</span>
<span class="source-line-no">2964</span><span id="line-2964"> .build(new Append(row).addColumn(FAMILY, Bytes.toBytes("B"), Bytes.toBytes("bb"))));</span>
<span class="source-line-no">2965</span><span id="line-2965"> assertTrue(res.isSuccess());</span>
<span class="source-line-no">2966</span><span id="line-2966"> assertEquals("bbb", Bytes.toString(res.getResult().getValue(FAMILY, Bytes.toBytes("B"))));</span>
<span class="source-line-no">2967</span><span id="line-2967"></span>
<span class="source-line-no">2968</span><span id="line-2968"> result = region.get(new Get(row).addColumn(FAMILY, Bytes.toBytes("B")));</span>
<span class="source-line-no">2969</span><span id="line-2969"> assertEquals("bbb", Bytes.toString(result.getValue(FAMILY, Bytes.toBytes("B"))));</span>
<span class="source-line-no">2970</span><span id="line-2970"></span>
<span class="source-line-no">2971</span><span id="line-2971"> // CheckAndAppend with a filter and wrong value</span>
<span class="source-line-no">2972</span><span id="line-2972"> res = region.checkAndMutate(CheckAndMutate.newBuilder(row)</span>
<span class="source-line-no">2973</span><span id="line-2973"> .ifMatches(new FilterList(</span>
<span class="source-line-no">2974</span><span id="line-2974"> new SingleColumnValueFilter(FAMILY, Bytes.toBytes("A"), CompareOperator.EQUAL,</span>
<span class="source-line-no">2975</span><span id="line-2975"> Bytes.toBytes("b")),</span>
<span class="source-line-no">2976</span><span id="line-2976"> new SingleColumnValueFilter(FAMILY, Bytes.toBytes("C"), CompareOperator.EQUAL,</span>
<span class="source-line-no">2977</span><span id="line-2977"> Bytes.toBytes("d"))))</span>
<span class="source-line-no">2978</span><span id="line-2978"> .build(new Append(row).addColumn(FAMILY, Bytes.toBytes("B"), Bytes.toBytes("bb"))));</span>
<span class="source-line-no">2979</span><span id="line-2979"> assertFalse(res.isSuccess());</span>
<span class="source-line-no">2980</span><span id="line-2980"> assertNull(res.getResult());</span>
<span class="source-line-no">2981</span><span id="line-2981"></span>
<span class="source-line-no">2982</span><span id="line-2982"> result = region.get(new Get(row).addColumn(FAMILY, Bytes.toBytes("B")));</span>
<span class="source-line-no">2983</span><span id="line-2983"> assertEquals("bbb", Bytes.toString(result.getValue(FAMILY, Bytes.toBytes("B"))));</span>
<span class="source-line-no">2984</span><span id="line-2984"> }</span>
<span class="source-line-no">2985</span><span id="line-2985"></span>
<span class="source-line-no">2986</span><span id="line-2986"> @Test</span>
<span class="source-line-no">2987</span><span id="line-2987"> public void testCheckAndIncrementAndAppend() throws Throwable {</span>
<span class="source-line-no">2988</span><span id="line-2988"> // Setting up region</span>
<span class="source-line-no">2989</span><span id="line-2989"> this.region = initHRegion(tableName, method, CONF, fam1);</span>
<span class="source-line-no">2990</span><span id="line-2990"></span>
<span class="source-line-no">2991</span><span id="line-2991"> // CheckAndMutate with Increment and Append</span>
<span class="source-line-no">2992</span><span id="line-2992"> CheckAndMutate checkAndMutate = CheckAndMutate.newBuilder(row).ifNotExists(fam1, qual)</span>
<span class="source-line-no">2993</span><span id="line-2993"> .build(new RowMutations(row).add((Mutation) new Increment(row).addColumn(fam1, qual1, 1L))</span>
<span class="source-line-no">2994</span><span id="line-2994"> .add((Mutation) new Append(row).addColumn(fam1, qual2, Bytes.toBytes("a"))));</span>
<span class="source-line-no">2995</span><span id="line-2995"></span>
<span class="source-line-no">2996</span><span id="line-2996"> CheckAndMutateResult result = region.checkAndMutate(checkAndMutate);</span>
<span class="source-line-no">2997</span><span id="line-2997"> assertTrue(result.isSuccess());</span>
<span class="source-line-no">2998</span><span id="line-2998"> assertEquals(1L, Bytes.toLong(result.getResult().getValue(fam1, qual1)));</span>
<span class="source-line-no">2999</span><span id="line-2999"> assertEquals("a", Bytes.toString(result.getResult().getValue(fam1, qual2)));</span>
<span class="source-line-no">3000</span><span id="line-3000"></span>
<span class="source-line-no">3001</span><span id="line-3001"> Result r = region.get(new Get(row));</span>
<span class="source-line-no">3002</span><span id="line-3002"> assertEquals(1L, Bytes.toLong(r.getValue(fam1, qual1)));</span>
<span class="source-line-no">3003</span><span id="line-3003"> assertEquals("a", Bytes.toString(r.getValue(fam1, qual2)));</span>
<span class="source-line-no">3004</span><span id="line-3004"></span>
<span class="source-line-no">3005</span><span id="line-3005"> // Set return results to false</span>
<span class="source-line-no">3006</span><span id="line-3006"> checkAndMutate = CheckAndMutate.newBuilder(row).ifNotExists(fam1, qual)</span>
<span class="source-line-no">3007</span><span id="line-3007"> .build(new RowMutations(row)</span>
<span class="source-line-no">3008</span><span id="line-3008"> .add((Mutation) new Increment(row).addColumn(fam1, qual1, 1L).setReturnResults(false))</span>
<span class="source-line-no">3009</span><span id="line-3009"> .add((Mutation) new Append(row).addColumn(fam1, qual2, Bytes.toBytes("a"))</span>
<span class="source-line-no">3010</span><span id="line-3010"> .setReturnResults(false)));</span>
<span class="source-line-no">3011</span><span id="line-3011"></span>
<span class="source-line-no">3012</span><span id="line-3012"> result = region.checkAndMutate(checkAndMutate);</span>
<span class="source-line-no">3013</span><span id="line-3013"> assertTrue(result.isSuccess());</span>
<span class="source-line-no">3014</span><span id="line-3014"> assertNull(result.getResult().getValue(fam1, qual1));</span>
<span class="source-line-no">3015</span><span id="line-3015"> assertNull(result.getResult().getValue(fam1, qual2));</span>
<span class="source-line-no">3016</span><span id="line-3016"></span>
<span class="source-line-no">3017</span><span id="line-3017"> r = region.get(new Get(row));</span>
<span class="source-line-no">3018</span><span id="line-3018"> assertEquals(2L, Bytes.toLong(r.getValue(fam1, qual1)));</span>
<span class="source-line-no">3019</span><span id="line-3019"> assertEquals("aa", Bytes.toString(r.getValue(fam1, qual2)));</span>
<span class="source-line-no">3020</span><span id="line-3020"></span>
<span class="source-line-no">3021</span><span id="line-3021"> checkAndMutate = CheckAndMutate.newBuilder(row).ifNotExists(fam1, qual)</span>
<span class="source-line-no">3022</span><span id="line-3022"> .build(new RowMutations(row).add((Mutation) new Increment(row).addColumn(fam1, qual1, 1L))</span>
<span class="source-line-no">3023</span><span id="line-3023"> .add((Mutation) new Append(row).addColumn(fam1, qual2, Bytes.toBytes("a"))</span>
<span class="source-line-no">3024</span><span id="line-3024"> .setReturnResults(false)));</span>
<span class="source-line-no">3025</span><span id="line-3025"></span>
<span class="source-line-no">3026</span><span id="line-3026"> result = region.checkAndMutate(checkAndMutate);</span>
<span class="source-line-no">3027</span><span id="line-3027"> assertTrue(result.isSuccess());</span>
<span class="source-line-no">3028</span><span id="line-3028"> assertEquals(3L, Bytes.toLong(result.getResult().getValue(fam1, qual1)));</span>
<span class="source-line-no">3029</span><span id="line-3029"> assertNull(result.getResult().getValue(fam1, qual2));</span>
<span class="source-line-no">3030</span><span id="line-3030"></span>
<span class="source-line-no">3031</span><span id="line-3031"> r = region.get(new Get(row));</span>
<span class="source-line-no">3032</span><span id="line-3032"> assertEquals(3L, Bytes.toLong(r.getValue(fam1, qual1)));</span>
<span class="source-line-no">3033</span><span id="line-3033"> assertEquals("aaa", Bytes.toString(r.getValue(fam1, qual2)));</span>
<span class="source-line-no">3034</span><span id="line-3034"> }</span>
<span class="source-line-no">3035</span><span id="line-3035"></span>
<span class="source-line-no">3036</span><span id="line-3036"> @Test</span>
<span class="source-line-no">3037</span><span id="line-3037"> public void testCheckAndRowMutations() throws Throwable {</span>
<span class="source-line-no">3038</span><span id="line-3038"> final byte[] row = Bytes.toBytes("row");</span>
<span class="source-line-no">3039</span><span id="line-3039"> final byte[] q1 = Bytes.toBytes("q1");</span>
<span class="source-line-no">3040</span><span id="line-3040"> final byte[] q2 = Bytes.toBytes("q2");</span>
<span class="source-line-no">3041</span><span id="line-3041"> final byte[] q3 = Bytes.toBytes("q3");</span>
<span class="source-line-no">3042</span><span id="line-3042"> final byte[] q4 = Bytes.toBytes("q4");</span>
<span class="source-line-no">3043</span><span id="line-3043"> final String v1 = "v1";</span>
<span class="source-line-no">3044</span><span id="line-3044"></span>
<span class="source-line-no">3045</span><span id="line-3045"> region = initHRegion(tableName, method, CONF, fam1);</span>
<span class="source-line-no">3046</span><span id="line-3046"></span>
<span class="source-line-no">3047</span><span id="line-3047"> // Initial values</span>
<span class="source-line-no">3048</span><span id="line-3048"> region</span>
<span class="source-line-no">3049</span><span id="line-3049"> .batchMutate(new Mutation[] { new Put(row).addColumn(fam1, q2, Bytes.toBytes("toBeDeleted")),</span>
<span class="source-line-no">3050</span><span id="line-3050"> new Put(row).addColumn(fam1, q3, Bytes.toBytes(5L)),</span>
<span class="source-line-no">3051</span><span id="line-3051"> new Put(row).addColumn(fam1, q4, Bytes.toBytes("a")), });</span>
<span class="source-line-no">3052</span><span id="line-3052"></span>
<span class="source-line-no">3053</span><span id="line-3053"> // Do CheckAndRowMutations</span>
<span class="source-line-no">3054</span><span id="line-3054"> CheckAndMutate checkAndMutate = CheckAndMutate.newBuilder(row).ifNotExists(fam1, q1).build(</span>
<span class="source-line-no">3055</span><span id="line-3055"> new RowMutations(row).add(Arrays.asList(new Put(row).addColumn(fam1, q1, Bytes.toBytes(v1)),</span>
<span class="source-line-no">3056</span><span id="line-3056"> new Delete(row).addColumns(fam1, q2), new Increment(row).addColumn(fam1, q3, 1),</span>
<span class="source-line-no">3057</span><span id="line-3057"> new Append(row).addColumn(fam1, q4, Bytes.toBytes("b")))));</span>
<span class="source-line-no">3058</span><span id="line-3058"></span>
<span class="source-line-no">3059</span><span id="line-3059"> CheckAndMutateResult result = region.checkAndMutate(checkAndMutate);</span>
<span class="source-line-no">3060</span><span id="line-3060"> assertTrue(result.isSuccess());</span>
<span class="source-line-no">3061</span><span id="line-3061"> assertEquals(6L, Bytes.toLong(result.getResult().getValue(fam1, q3)));</span>
<span class="source-line-no">3062</span><span id="line-3062"> assertEquals("ab", Bytes.toString(result.getResult().getValue(fam1, q4)));</span>
<span class="source-line-no">3063</span><span id="line-3063"></span>
<span class="source-line-no">3064</span><span id="line-3064"> // Verify the value</span>
<span class="source-line-no">3065</span><span id="line-3065"> Result r = region.get(new Get(row));</span>
<span class="source-line-no">3066</span><span id="line-3066"> assertEquals(v1, Bytes.toString(r.getValue(fam1, q1)));</span>
<span class="source-line-no">3067</span><span id="line-3067"> assertNull(r.getValue(fam1, q2));</span>
<span class="source-line-no">3068</span><span id="line-3068"> assertEquals(6L, Bytes.toLong(r.getValue(fam1, q3)));</span>
<span class="source-line-no">3069</span><span id="line-3069"> assertEquals("ab", Bytes.toString(r.getValue(fam1, q4)));</span>
<span class="source-line-no">3070</span><span id="line-3070"></span>
<span class="source-line-no">3071</span><span id="line-3071"> // Do CheckAndRowMutations again</span>
<span class="source-line-no">3072</span><span id="line-3072"> checkAndMutate = CheckAndMutate.newBuilder(row).ifNotExists(fam1, q1)</span>
<span class="source-line-no">3073</span><span id="line-3073"> .build(new RowMutations(row).add(Arrays.asList(new Delete(row).addColumns(fam1, q1),</span>
<span class="source-line-no">3074</span><span id="line-3074"> new Put(row).addColumn(fam1, q2, Bytes.toBytes(v1)),</span>
<span class="source-line-no">3075</span><span id="line-3075"> new Increment(row).addColumn(fam1, q3, 1),</span>
<span class="source-line-no">3076</span><span id="line-3076"> new Append(row).addColumn(fam1, q4, Bytes.toBytes("b")))));</span>
<span class="source-line-no">3077</span><span id="line-3077"></span>
<span class="source-line-no">3078</span><span id="line-3078"> result = region.checkAndMutate(checkAndMutate);</span>
<span class="source-line-no">3079</span><span id="line-3079"> assertFalse(result.isSuccess());</span>
<span class="source-line-no">3080</span><span id="line-3080"> assertNull(result.getResult());</span>
<span class="source-line-no">3081</span><span id="line-3081"></span>
<span class="source-line-no">3082</span><span id="line-3082"> // Verify the value</span>
<span class="source-line-no">3083</span><span id="line-3083"> r = region.get(new Get(row));</span>
<span class="source-line-no">3084</span><span id="line-3084"> assertEquals(v1, Bytes.toString(r.getValue(fam1, q1)));</span>
<span class="source-line-no">3085</span><span id="line-3085"> assertNull(r.getValue(fam1, q2));</span>
<span class="source-line-no">3086</span><span id="line-3086"> assertEquals(6L, Bytes.toLong(r.getValue(fam1, q3)));</span>
<span class="source-line-no">3087</span><span id="line-3087"> assertEquals("ab", Bytes.toString(r.getValue(fam1, q4)));</span>
<span class="source-line-no">3088</span><span id="line-3088"> }</span>
<span class="source-line-no">3089</span><span id="line-3089"></span>
<span class="source-line-no">3090</span><span id="line-3090"> // ////////////////////////////////////////////////////////////////////////////</span>
<span class="source-line-no">3091</span><span id="line-3091"> // Delete tests</span>
<span class="source-line-no">3092</span><span id="line-3092"> // ////////////////////////////////////////////////////////////////////////////</span>
<span class="source-line-no">3093</span><span id="line-3093"> @Test</span>
<span class="source-line-no">3094</span><span id="line-3094"> public void testDelete_multiDeleteColumn() throws IOException {</span>
<span class="source-line-no">3095</span><span id="line-3095"> byte[] row1 = Bytes.toBytes("row1");</span>
<span class="source-line-no">3096</span><span id="line-3096"> byte[] fam1 = Bytes.toBytes("fam1");</span>
<span class="source-line-no">3097</span><span id="line-3097"> byte[] qual = Bytes.toBytes("qualifier");</span>
<span class="source-line-no">3098</span><span id="line-3098"> byte[] value = Bytes.toBytes("value");</span>
<span class="source-line-no">3099</span><span id="line-3099"></span>
<span class="source-line-no">3100</span><span id="line-3100"> Put put = new Put(row1);</span>
<span class="source-line-no">3101</span><span id="line-3101"> put.addColumn(fam1, qual, 1, value);</span>
<span class="source-line-no">3102</span><span id="line-3102"> put.addColumn(fam1, qual, 2, value);</span>
<span class="source-line-no">3103</span><span id="line-3103"></span>
<span class="source-line-no">3104</span><span id="line-3104"> this.region = initHRegion(tableName, method, CONF, fam1);</span>
<span class="source-line-no">3105</span><span id="line-3105"> region.put(put);</span>
<span class="source-line-no">3106</span><span id="line-3106"></span>
<span class="source-line-no">3107</span><span id="line-3107"> // We do support deleting more than 1 'latest' version</span>
<span class="source-line-no">3108</span><span id="line-3108"> Delete delete = new Delete(row1);</span>
<span class="source-line-no">3109</span><span id="line-3109"> delete.addColumn(fam1, qual);</span>
<span class="source-line-no">3110</span><span id="line-3110"> delete.addColumn(fam1, qual);</span>
<span class="source-line-no">3111</span><span id="line-3111"> region.delete(delete);</span>
<span class="source-line-no">3112</span><span id="line-3112"></span>
<span class="source-line-no">3113</span><span id="line-3113"> Get get = new Get(row1);</span>
<span class="source-line-no">3114</span><span id="line-3114"> get.addFamily(fam1);</span>
<span class="source-line-no">3115</span><span id="line-3115"> Result r = region.get(get);</span>
<span class="source-line-no">3116</span><span id="line-3116"> assertEquals(0, r.size());</span>
<span class="source-line-no">3117</span><span id="line-3117"> }</span>
<span class="source-line-no">3118</span><span id="line-3118"></span>
<span class="source-line-no">3119</span><span id="line-3119"> @Test</span>
<span class="source-line-no">3120</span><span id="line-3120"> public void testDelete_CheckFamily() throws IOException {</span>
<span class="source-line-no">3121</span><span id="line-3121"> byte[] row1 = Bytes.toBytes("row1");</span>
<span class="source-line-no">3122</span><span id="line-3122"> byte[] fam1 = Bytes.toBytes("fam1");</span>
<span class="source-line-no">3123</span><span id="line-3123"> byte[] fam2 = Bytes.toBytes("fam2");</span>
<span class="source-line-no">3124</span><span id="line-3124"> byte[] fam3 = Bytes.toBytes("fam3");</span>
<span class="source-line-no">3125</span><span id="line-3125"> byte[] fam4 = Bytes.toBytes("fam4");</span>
<span class="source-line-no">3126</span><span id="line-3126"></span>
<span class="source-line-no">3127</span><span id="line-3127"> // Setting up region</span>
<span class="source-line-no">3128</span><span id="line-3128"> this.region = initHRegion(tableName, method, CONF, fam1, fam2, fam3);</span>
<span class="source-line-no">3129</span><span id="line-3129"> List&lt;Cell&gt; kvs = new ArrayList&lt;&gt;();</span>
<span class="source-line-no">3130</span><span id="line-3130"> kvs.add(new KeyValue(row1, fam4, null, null));</span>
<span class="source-line-no">3131</span><span id="line-3131"></span>
<span class="source-line-no">3132</span><span id="line-3132"> byte[] forUnitTestsOnly = Bytes.toBytes("ForUnitTestsOnly");</span>
<span class="source-line-no">3133</span><span id="line-3133"></span>
<span class="source-line-no">3134</span><span id="line-3134"> // testing existing family</span>
<span class="source-line-no">3135</span><span id="line-3135"> NavigableMap&lt;byte[], List&lt;Cell&gt;&gt; deleteMap = new TreeMap&lt;&gt;(Bytes.BYTES_COMPARATOR);</span>
<span class="source-line-no">3136</span><span id="line-3136"> deleteMap.put(fam2, kvs);</span>
<span class="source-line-no">3137</span><span id="line-3137"> region.delete(new Delete(forUnitTestsOnly, HConstants.LATEST_TIMESTAMP, deleteMap));</span>
<span class="source-line-no">3138</span><span id="line-3138"></span>
<span class="source-line-no">3139</span><span id="line-3139"> // testing non existing family</span>
<span class="source-line-no">3140</span><span id="line-3140"> NavigableMap&lt;byte[], List&lt;Cell&gt;&gt; deleteMap2 = new TreeMap&lt;&gt;(Bytes.BYTES_COMPARATOR);</span>
<span class="source-line-no">3141</span><span id="line-3141"> deleteMap2.put(fam4, kvs);</span>
<span class="source-line-no">3142</span><span id="line-3142"> assertThrows("Family " + Bytes.toString(fam4) + " does exist",</span>
<span class="source-line-no">3143</span><span id="line-3143"> NoSuchColumnFamilyException.class,</span>
<span class="source-line-no">3144</span><span id="line-3144"> () -&gt; region.delete(new Delete(forUnitTestsOnly, HConstants.LATEST_TIMESTAMP, deleteMap2)));</span>
<span class="source-line-no">3145</span><span id="line-3145"> }</span>
<span class="source-line-no">3146</span><span id="line-3146"></span>
<span class="source-line-no">3147</span><span id="line-3147"> @Test</span>
<span class="source-line-no">3148</span><span id="line-3148"> public void testDelete_mixed() throws IOException, InterruptedException {</span>
<span class="source-line-no">3149</span><span id="line-3149"> byte[] fam = Bytes.toBytes("info");</span>
<span class="source-line-no">3150</span><span id="line-3150"> byte[][] families = { fam };</span>
<span class="source-line-no">3151</span><span id="line-3151"> this.region = initHRegion(tableName, method, CONF, families);</span>
<span class="source-line-no">3152</span><span id="line-3152"> EnvironmentEdgeManagerTestHelper.injectEdge(new IncrementingEnvironmentEdge());</span>
<span class="source-line-no">3153</span><span id="line-3153"></span>
<span class="source-line-no">3154</span><span id="line-3154"> byte[] row = Bytes.toBytes("table_name");</span>
<span class="source-line-no">3155</span><span id="line-3155"> // column names</span>
<span class="source-line-no">3156</span><span id="line-3156"> byte[] serverinfo = Bytes.toBytes("serverinfo");</span>
<span class="source-line-no">3157</span><span id="line-3157"> byte[] splitA = Bytes.toBytes("splitA");</span>
<span class="source-line-no">3158</span><span id="line-3158"> byte[] splitB = Bytes.toBytes("splitB");</span>
<span class="source-line-no">3159</span><span id="line-3159"></span>
<span class="source-line-no">3160</span><span id="line-3160"> // add some data:</span>
<span class="source-line-no">3161</span><span id="line-3161"> Put put = new Put(row);</span>
<span class="source-line-no">3162</span><span id="line-3162"> put.addColumn(fam, splitA, Bytes.toBytes("reference_A"));</span>
<span class="source-line-no">3163</span><span id="line-3163"> region.put(put);</span>
<span class="source-line-no">3164</span><span id="line-3164"></span>
<span class="source-line-no">3165</span><span id="line-3165"> put = new Put(row);</span>
<span class="source-line-no">3166</span><span id="line-3166"> put.addColumn(fam, splitB, Bytes.toBytes("reference_B"));</span>
<span class="source-line-no">3167</span><span id="line-3167"> region.put(put);</span>
<span class="source-line-no">3168</span><span id="line-3168"></span>
<span class="source-line-no">3169</span><span id="line-3169"> put = new Put(row);</span>
<span class="source-line-no">3170</span><span id="line-3170"> put.addColumn(fam, serverinfo, Bytes.toBytes("ip_address"));</span>
<span class="source-line-no">3171</span><span id="line-3171"> region.put(put);</span>
<span class="source-line-no">3172</span><span id="line-3172"></span>
<span class="source-line-no">3173</span><span id="line-3173"> // ok now delete a split:</span>
<span class="source-line-no">3174</span><span id="line-3174"> Delete delete = new Delete(row);</span>
<span class="source-line-no">3175</span><span id="line-3175"> delete.addColumns(fam, splitA);</span>
<span class="source-line-no">3176</span><span id="line-3176"> region.delete(delete);</span>
<span class="source-line-no">3177</span><span id="line-3177"></span>
<span class="source-line-no">3178</span><span id="line-3178"> // assert some things:</span>
<span class="source-line-no">3179</span><span id="line-3179"> Get get = new Get(row).addColumn(fam, serverinfo);</span>
<span class="source-line-no">3180</span><span id="line-3180"> Result result = region.get(get);</span>
<span class="source-line-no">3181</span><span id="line-3181"> assertEquals(1, result.size());</span>
<span class="source-line-no">3182</span><span id="line-3182"></span>
<span class="source-line-no">3183</span><span id="line-3183"> get = new Get(row).addColumn(fam, splitA);</span>
<span class="source-line-no">3184</span><span id="line-3184"> result = region.get(get);</span>
<span class="source-line-no">3185</span><span id="line-3185"> assertEquals(0, result.size());</span>
<span class="source-line-no">3186</span><span id="line-3186"></span>
<span class="source-line-no">3187</span><span id="line-3187"> get = new Get(row).addColumn(fam, splitB);</span>
<span class="source-line-no">3188</span><span id="line-3188"> result = region.get(get);</span>
<span class="source-line-no">3189</span><span id="line-3189"> assertEquals(1, result.size());</span>
<span class="source-line-no">3190</span><span id="line-3190"></span>
<span class="source-line-no">3191</span><span id="line-3191"> // Assert that after a delete, I can put.</span>
<span class="source-line-no">3192</span><span id="line-3192"> put = new Put(row);</span>
<span class="source-line-no">3193</span><span id="line-3193"> put.addColumn(fam, splitA, Bytes.toBytes("reference_A"));</span>
<span class="source-line-no">3194</span><span id="line-3194"> region.put(put);</span>
<span class="source-line-no">3195</span><span id="line-3195"> get = new Get(row);</span>
<span class="source-line-no">3196</span><span id="line-3196"> result = region.get(get);</span>
<span class="source-line-no">3197</span><span id="line-3197"> assertEquals(3, result.size());</span>
<span class="source-line-no">3198</span><span id="line-3198"></span>
<span class="source-line-no">3199</span><span id="line-3199"> // Now delete all... then test I can add stuff back</span>
<span class="source-line-no">3200</span><span id="line-3200"> delete = new Delete(row);</span>
<span class="source-line-no">3201</span><span id="line-3201"> region.delete(delete);</span>
<span class="source-line-no">3202</span><span id="line-3202"> assertEquals(0, region.get(get).size());</span>
<span class="source-line-no">3203</span><span id="line-3203"></span>
<span class="source-line-no">3204</span><span id="line-3204"> region.put(new Put(row).addColumn(fam, splitA, Bytes.toBytes("reference_A")));</span>
<span class="source-line-no">3205</span><span id="line-3205"> result = region.get(get);</span>
<span class="source-line-no">3206</span><span id="line-3206"> assertEquals(1, result.size());</span>
<span class="source-line-no">3207</span><span id="line-3207"> }</span>
<span class="source-line-no">3208</span><span id="line-3208"></span>
<span class="source-line-no">3209</span><span id="line-3209"> @Test</span>
<span class="source-line-no">3210</span><span id="line-3210"> public void testDeleteRowWithFutureTs() throws IOException {</span>
<span class="source-line-no">3211</span><span id="line-3211"> byte[] fam = Bytes.toBytes("info");</span>
<span class="source-line-no">3212</span><span id="line-3212"> byte[][] families = { fam };</span>
<span class="source-line-no">3213</span><span id="line-3213"> this.region = initHRegion(tableName, method, CONF, families);</span>
<span class="source-line-no">3214</span><span id="line-3214"> byte[] row = Bytes.toBytes("table_name");</span>
<span class="source-line-no">3215</span><span id="line-3215"> // column names</span>
<span class="source-line-no">3216</span><span id="line-3216"> byte[] serverinfo = Bytes.toBytes("serverinfo");</span>
<span class="source-line-no">3217</span><span id="line-3217"></span>
<span class="source-line-no">3218</span><span id="line-3218"> // add data in the far future</span>
<span class="source-line-no">3219</span><span id="line-3219"> Put put = new Put(row);</span>
<span class="source-line-no">3220</span><span id="line-3220"> put.addColumn(fam, serverinfo, HConstants.LATEST_TIMESTAMP - 5, Bytes.toBytes("value"));</span>
<span class="source-line-no">3221</span><span id="line-3221"> region.put(put);</span>
<span class="source-line-no">3222</span><span id="line-3222"></span>
<span class="source-line-no">3223</span><span id="line-3223"> // now delete something in the present</span>
<span class="source-line-no">3224</span><span id="line-3224"> Delete delete = new Delete(row);</span>
<span class="source-line-no">3225</span><span id="line-3225"> region.delete(delete);</span>
<span class="source-line-no">3226</span><span id="line-3226"></span>
<span class="source-line-no">3227</span><span id="line-3227"> // make sure we still see our data</span>
<span class="source-line-no">3228</span><span id="line-3228"> Get get = new Get(row).addColumn(fam, serverinfo);</span>
<span class="source-line-no">3229</span><span id="line-3229"> Result result = region.get(get);</span>
<span class="source-line-no">3230</span><span id="line-3230"> assertEquals(1, result.size());</span>
<span class="source-line-no">3231</span><span id="line-3231"></span>
<span class="source-line-no">3232</span><span id="line-3232"> // delete the future row</span>
<span class="source-line-no">3233</span><span id="line-3233"> delete = new Delete(row, HConstants.LATEST_TIMESTAMP - 3);</span>
<span class="source-line-no">3234</span><span id="line-3234"> region.delete(delete);</span>
<span class="source-line-no">3235</span><span id="line-3235"></span>
<span class="source-line-no">3236</span><span id="line-3236"> // make sure it is gone</span>
<span class="source-line-no">3237</span><span id="line-3237"> get = new Get(row).addColumn(fam, serverinfo);</span>
<span class="source-line-no">3238</span><span id="line-3238"> result = region.get(get);</span>
<span class="source-line-no">3239</span><span id="line-3239"> assertEquals(0, result.size());</span>
<span class="source-line-no">3240</span><span id="line-3240"> }</span>
<span class="source-line-no">3241</span><span id="line-3241"></span>
<span class="source-line-no">3242</span><span id="line-3242"> /**</span>
<span class="source-line-no">3243</span><span id="line-3243"> * Tests that the special LATEST_TIMESTAMP option for puts gets replaced by the actual timestamp</span>
<span class="source-line-no">3244</span><span id="line-3244"> */</span>
<span class="source-line-no">3245</span><span id="line-3245"> @Test</span>
<span class="source-line-no">3246</span><span id="line-3246"> public void testPutWithLatestTS() throws IOException {</span>
<span class="source-line-no">3247</span><span id="line-3247"> byte[] fam = Bytes.toBytes("info");</span>
<span class="source-line-no">3248</span><span id="line-3248"> byte[][] families = { fam };</span>
<span class="source-line-no">3249</span><span id="line-3249"> this.region = initHRegion(tableName, method, CONF, families);</span>
<span class="source-line-no">3250</span><span id="line-3250"> byte[] row = Bytes.toBytes("row1");</span>
<span class="source-line-no">3251</span><span id="line-3251"> // column names</span>
<span class="source-line-no">3252</span><span id="line-3252"> byte[] qual = Bytes.toBytes("qual");</span>
<span class="source-line-no">3253</span><span id="line-3253"></span>
<span class="source-line-no">3254</span><span id="line-3254"> // add data with LATEST_TIMESTAMP, put without WAL</span>
<span class="source-line-no">3255</span><span id="line-3255"> Put put = new Put(row);</span>
<span class="source-line-no">3256</span><span id="line-3256"> put.addColumn(fam, qual, HConstants.LATEST_TIMESTAMP, Bytes.toBytes("value"));</span>
<span class="source-line-no">3257</span><span id="line-3257"> region.put(put);</span>
<span class="source-line-no">3258</span><span id="line-3258"></span>
<span class="source-line-no">3259</span><span id="line-3259"> // Make sure it shows up with an actual timestamp</span>
<span class="source-line-no">3260</span><span id="line-3260"> Get get = new Get(row).addColumn(fam, qual);</span>
<span class="source-line-no">3261</span><span id="line-3261"> Result result = region.get(get);</span>
<span class="source-line-no">3262</span><span id="line-3262"> assertEquals(1, result.size());</span>
<span class="source-line-no">3263</span><span id="line-3263"> Cell kv = result.rawCells()[0];</span>
<span class="source-line-no">3264</span><span id="line-3264"> LOG.info("Got: " + kv);</span>
<span class="source-line-no">3265</span><span id="line-3265"> assertTrue("LATEST_TIMESTAMP was not replaced with real timestamp",</span>
<span class="source-line-no">3266</span><span id="line-3266"> kv.getTimestamp() != HConstants.LATEST_TIMESTAMP);</span>
<span class="source-line-no">3267</span><span id="line-3267"></span>
<span class="source-line-no">3268</span><span id="line-3268"> // Check same with WAL enabled (historically these took different</span>
<span class="source-line-no">3269</span><span id="line-3269"> // code paths, so check both)</span>
<span class="source-line-no">3270</span><span id="line-3270"> row = Bytes.toBytes("row2");</span>
<span class="source-line-no">3271</span><span id="line-3271"> put = new Put(row);</span>
<span class="source-line-no">3272</span><span id="line-3272"> put.addColumn(fam, qual, HConstants.LATEST_TIMESTAMP, Bytes.toBytes("value"));</span>
<span class="source-line-no">3273</span><span id="line-3273"> region.put(put);</span>
<span class="source-line-no">3274</span><span id="line-3274"></span>
<span class="source-line-no">3275</span><span id="line-3275"> // Make sure it shows up with an actual timestamp</span>
<span class="source-line-no">3276</span><span id="line-3276"> get = new Get(row).addColumn(fam, qual);</span>
<span class="source-line-no">3277</span><span id="line-3277"> result = region.get(get);</span>
<span class="source-line-no">3278</span><span id="line-3278"> assertEquals(1, result.size());</span>
<span class="source-line-no">3279</span><span id="line-3279"> kv = result.rawCells()[0];</span>
<span class="source-line-no">3280</span><span id="line-3280"> LOG.info("Got: " + kv);</span>
<span class="source-line-no">3281</span><span id="line-3281"> assertTrue("LATEST_TIMESTAMP was not replaced with real timestamp",</span>
<span class="source-line-no">3282</span><span id="line-3282"> kv.getTimestamp() != HConstants.LATEST_TIMESTAMP);</span>
<span class="source-line-no">3283</span><span id="line-3283"> }</span>
<span class="source-line-no">3284</span><span id="line-3284"></span>
<span class="source-line-no">3285</span><span id="line-3285"> /**</span>
<span class="source-line-no">3286</span><span id="line-3286"> * Tests that there is server-side filtering for invalid timestamp upper bound. Note that the</span>
<span class="source-line-no">3287</span><span id="line-3287"> * timestamp lower bound is automatically handled for us by the TTL field.</span>
<span class="source-line-no">3288</span><span id="line-3288"> */</span>
<span class="source-line-no">3289</span><span id="line-3289"> @Test</span>
<span class="source-line-no">3290</span><span id="line-3290"> public void testPutWithTsSlop() throws IOException {</span>
<span class="source-line-no">3291</span><span id="line-3291"> byte[] fam = Bytes.toBytes("info");</span>
<span class="source-line-no">3292</span><span id="line-3292"> byte[][] families = { fam };</span>
<span class="source-line-no">3293</span><span id="line-3293"></span>
<span class="source-line-no">3294</span><span id="line-3294"> // add data with a timestamp that is too recent for range. Ensure assert</span>
<span class="source-line-no">3295</span><span id="line-3295"> CONF.setInt("hbase.hregion.keyvalue.timestamp.slop.millisecs", 1000);</span>
<span class="source-line-no">3296</span><span id="line-3296"> this.region = initHRegion(tableName, method, CONF, families);</span>
<span class="source-line-no">3297</span><span id="line-3297"> boolean caughtExcep = false;</span>
<span class="source-line-no">3298</span><span id="line-3298"> try {</span>
<span class="source-line-no">3299</span><span id="line-3299"> // no TS specified == use latest. should not error</span>
<span class="source-line-no">3300</span><span id="line-3300"> region.put(new Put(row).addColumn(fam, Bytes.toBytes("qual"), Bytes.toBytes("value")));</span>
<span class="source-line-no">3301</span><span id="line-3301"> // TS out of range. should error</span>
<span class="source-line-no">3302</span><span id="line-3302"> region.put(new Put(row).addColumn(fam, Bytes.toBytes("qual"),</span>
<span class="source-line-no">3303</span><span id="line-3303"> EnvironmentEdgeManager.currentTime() + 2000, Bytes.toBytes("value")));</span>
<span class="source-line-no">3304</span><span id="line-3304"> fail("Expected IOE for TS out of configured timerange");</span>
<span class="source-line-no">3305</span><span id="line-3305"> } catch (FailedSanityCheckException ioe) {</span>
<span class="source-line-no">3306</span><span id="line-3306"> LOG.debug("Received expected exception", ioe);</span>
<span class="source-line-no">3307</span><span id="line-3307"> caughtExcep = true;</span>
<span class="source-line-no">3308</span><span id="line-3308"> }</span>
<span class="source-line-no">3309</span><span id="line-3309"> assertTrue("Should catch FailedSanityCheckException", caughtExcep);</span>
<span class="source-line-no">3310</span><span id="line-3310"> }</span>
<span class="source-line-no">3311</span><span id="line-3311"></span>
<span class="source-line-no">3312</span><span id="line-3312"> @Test</span>
<span class="source-line-no">3313</span><span id="line-3313"> public void testScanner_DeleteOneFamilyNotAnother() throws IOException {</span>
<span class="source-line-no">3314</span><span id="line-3314"> byte[] fam1 = Bytes.toBytes("columnA");</span>
<span class="source-line-no">3315</span><span id="line-3315"> byte[] fam2 = Bytes.toBytes("columnB");</span>
<span class="source-line-no">3316</span><span id="line-3316"> this.region = initHRegion(tableName, method, CONF, fam1, fam2);</span>
<span class="source-line-no">3317</span><span id="line-3317"> byte[] rowA = Bytes.toBytes("rowA");</span>
<span class="source-line-no">3318</span><span id="line-3318"> byte[] rowB = Bytes.toBytes("rowB");</span>
<span class="source-line-no">3319</span><span id="line-3319"></span>
<span class="source-line-no">3320</span><span id="line-3320"> byte[] value = Bytes.toBytes("value");</span>
<span class="source-line-no">3321</span><span id="line-3321"></span>
<span class="source-line-no">3322</span><span id="line-3322"> Delete delete = new Delete(rowA);</span>
<span class="source-line-no">3323</span><span id="line-3323"> delete.addFamily(fam1);</span>
<span class="source-line-no">3324</span><span id="line-3324"></span>
<span class="source-line-no">3325</span><span id="line-3325"> region.delete(delete);</span>
<span class="source-line-no">3326</span><span id="line-3326"></span>
<span class="source-line-no">3327</span><span id="line-3327"> // now create data.</span>
<span class="source-line-no">3328</span><span id="line-3328"> Put put = new Put(rowA);</span>
<span class="source-line-no">3329</span><span id="line-3329"> put.addColumn(fam2, null, value);</span>
<span class="source-line-no">3330</span><span id="line-3330"> region.put(put);</span>
<span class="source-line-no">3331</span><span id="line-3331"></span>
<span class="source-line-no">3332</span><span id="line-3332"> put = new Put(rowB);</span>
<span class="source-line-no">3333</span><span id="line-3333"> put.addColumn(fam1, null, value);</span>
<span class="source-line-no">3334</span><span id="line-3334"> put.addColumn(fam2, null, value);</span>
<span class="source-line-no">3335</span><span id="line-3335"> region.put(put);</span>
<span class="source-line-no">3336</span><span id="line-3336"></span>
<span class="source-line-no">3337</span><span id="line-3337"> Scan scan = new Scan();</span>
<span class="source-line-no">3338</span><span id="line-3338"> scan.addFamily(fam1).addFamily(fam2);</span>
<span class="source-line-no">3339</span><span id="line-3339"> try (InternalScanner s = region.getScanner(scan)) {</span>
<span class="source-line-no">3340</span><span id="line-3340"> List&lt;Cell&gt; results = new ArrayList&lt;&gt;();</span>
<span class="source-line-no">3341</span><span id="line-3341"> s.next(results);</span>
<span class="source-line-no">3342</span><span id="line-3342"> assertTrue(CellUtil.matchingRows(results.get(0), rowA));</span>
<span class="source-line-no">3343</span><span id="line-3343"></span>
<span class="source-line-no">3344</span><span id="line-3344"> results.clear();</span>
<span class="source-line-no">3345</span><span id="line-3345"> s.next(results);</span>
<span class="source-line-no">3346</span><span id="line-3346"> assertTrue(CellUtil.matchingRows(results.get(0), rowB));</span>
<span class="source-line-no">3347</span><span id="line-3347"> }</span>
<span class="source-line-no">3348</span><span id="line-3348"> }</span>
<span class="source-line-no">3349</span><span id="line-3349"></span>
<span class="source-line-no">3350</span><span id="line-3350"> @Test</span>
<span class="source-line-no">3351</span><span id="line-3351"> public void testDataInMemoryWithoutWAL() throws IOException {</span>
<span class="source-line-no">3352</span><span id="line-3352"> FileSystem fs = FileSystem.get(CONF);</span>
<span class="source-line-no">3353</span><span id="line-3353"> Path rootDir = new Path(dir + "testDataInMemoryWithoutWAL");</span>
<span class="source-line-no">3354</span><span id="line-3354"> FSHLog hLog = new FSHLog(fs, rootDir, "testDataInMemoryWithoutWAL", CONF);</span>
<span class="source-line-no">3355</span><span id="line-3355"> hLog.init();</span>
<span class="source-line-no">3356</span><span id="line-3356"> // This chunk creation is done throughout the code base. Do we want to move it into core?</span>
<span class="source-line-no">3357</span><span id="line-3357"> // It is missing from this test. W/o it we NPE.</span>
<span class="source-line-no">3358</span><span id="line-3358"> region = initHRegion(tableName, null, null, CONF, false, Durability.SYNC_WAL, hLog,</span>
<span class="source-line-no">3359</span><span id="line-3359"> COLUMN_FAMILY_BYTES);</span>
<span class="source-line-no">3360</span><span id="line-3360"></span>
<span class="source-line-no">3361</span><span id="line-3361"> Cell originalCell = ExtendedCellBuilderFactory.create(CellBuilderType.DEEP_COPY).setRow(row)</span>
<span class="source-line-no">3362</span><span id="line-3362"> .setFamily(COLUMN_FAMILY_BYTES).setQualifier(qual1)</span>
<span class="source-line-no">3363</span><span id="line-3363"> .setTimestamp(EnvironmentEdgeManager.currentTime()).setType(KeyValue.Type.Put.getCode())</span>
<span class="source-line-no">3364</span><span id="line-3364"> .setValue(value1).build();</span>
<span class="source-line-no">3365</span><span id="line-3365"> final long originalSize = originalCell.getSerializedSize();</span>
<span class="source-line-no">3366</span><span id="line-3366"></span>
<span class="source-line-no">3367</span><span id="line-3367"> Cell addCell = ExtendedCellBuilderFactory.create(CellBuilderType.DEEP_COPY).setRow(row)</span>
<span class="source-line-no">3368</span><span id="line-3368"> .setFamily(COLUMN_FAMILY_BYTES).setQualifier(qual1)</span>
<span class="source-line-no">3369</span><span id="line-3369"> .setTimestamp(EnvironmentEdgeManager.currentTime()).setType(KeyValue.Type.Put.getCode())</span>
<span class="source-line-no">3370</span><span id="line-3370"> .setValue(Bytes.toBytes("xxxxxxxxxx")).build();</span>
<span class="source-line-no">3371</span><span id="line-3371"> final long addSize = addCell.getSerializedSize();</span>
<span class="source-line-no">3372</span><span id="line-3372"></span>
<span class="source-line-no">3373</span><span id="line-3373"> LOG.info("originalSize:" + originalSize + ", addSize:" + addSize);</span>
<span class="source-line-no">3374</span><span id="line-3374"> // start test. We expect that the addPut's durability will be replaced</span>
<span class="source-line-no">3375</span><span id="line-3375"> // by originalPut's durability.</span>
<span class="source-line-no">3376</span><span id="line-3376"></span>
<span class="source-line-no">3377</span><span id="line-3377"> // case 1:</span>
<span class="source-line-no">3378</span><span id="line-3378"> testDataInMemoryWithoutWAL(region,</span>
<span class="source-line-no">3379</span><span id="line-3379"> new Put(row).add(originalCell).setDurability(Durability.SKIP_WAL),</span>
<span class="source-line-no">3380</span><span id="line-3380"> new Put(row).add(addCell).setDurability(Durability.SKIP_WAL), originalSize + addSize);</span>
<span class="source-line-no">3381</span><span id="line-3381"></span>
<span class="source-line-no">3382</span><span id="line-3382"> // case 2:</span>
<span class="source-line-no">3383</span><span id="line-3383"> testDataInMemoryWithoutWAL(region,</span>
<span class="source-line-no">3384</span><span id="line-3384"> new Put(row).add(originalCell).setDurability(Durability.SKIP_WAL),</span>
<span class="source-line-no">3385</span><span id="line-3385"> new Put(row).add(addCell).setDurability(Durability.SYNC_WAL), originalSize + addSize);</span>
<span class="source-line-no">3386</span><span id="line-3386"></span>
<span class="source-line-no">3387</span><span id="line-3387"> // case 3:</span>
<span class="source-line-no">3388</span><span id="line-3388"> testDataInMemoryWithoutWAL(region,</span>
<span class="source-line-no">3389</span><span id="line-3389"> new Put(row).add(originalCell).setDurability(Durability.SYNC_WAL),</span>
<span class="source-line-no">3390</span><span id="line-3390"> new Put(row).add(addCell).setDurability(Durability.SKIP_WAL), 0);</span>
<span class="source-line-no">3391</span><span id="line-3391"></span>
<span class="source-line-no">3392</span><span id="line-3392"> // case 4:</span>
<span class="source-line-no">3393</span><span id="line-3393"> testDataInMemoryWithoutWAL(region,</span>
<span class="source-line-no">3394</span><span id="line-3394"> new Put(row).add(originalCell).setDurability(Durability.SYNC_WAL),</span>
<span class="source-line-no">3395</span><span id="line-3395"> new Put(row).add(addCell).setDurability(Durability.SYNC_WAL), 0);</span>
<span class="source-line-no">3396</span><span id="line-3396"> }</span>
<span class="source-line-no">3397</span><span id="line-3397"></span>
<span class="source-line-no">3398</span><span id="line-3398"> private static void testDataInMemoryWithoutWAL(HRegion region, Put originalPut, final Put addPut,</span>
<span class="source-line-no">3399</span><span id="line-3399"> long delta) throws IOException {</span>
<span class="source-line-no">3400</span><span id="line-3400"> final long initSize = region.getDataInMemoryWithoutWAL();</span>
<span class="source-line-no">3401</span><span id="line-3401"> // save normalCPHost and replaced by mockedCPHost</span>
<span class="source-line-no">3402</span><span id="line-3402"> RegionCoprocessorHost normalCPHost = region.getCoprocessorHost();</span>
<span class="source-line-no">3403</span><span id="line-3403"> RegionCoprocessorHost mockedCPHost = mock(RegionCoprocessorHost.class);</span>
<span class="source-line-no">3404</span><span id="line-3404"> // Because the preBatchMutate returns void, we can't do usual Mockito when...then form. Must</span>
<span class="source-line-no">3405</span><span id="line-3405"> // do below format (from Mockito doc).</span>
<span class="source-line-no">3406</span><span id="line-3406"> doAnswer(new Answer&lt;Void&gt;() {</span>
<span class="source-line-no">3407</span><span id="line-3407"> @Override</span>
<span class="source-line-no">3408</span><span id="line-3408"> public Void answer(InvocationOnMock invocation) throws Throwable {</span>
<span class="source-line-no">3409</span><span id="line-3409"> MiniBatchOperationInProgress&lt;Mutation&gt; mb = invocation.getArgument(0);</span>
<span class="source-line-no">3410</span><span id="line-3410"> mb.addOperationsFromCP(0, new Mutation[] { addPut });</span>
<span class="source-line-no">3411</span><span id="line-3411"> return null;</span>
<span class="source-line-no">3412</span><span id="line-3412"> }</span>
<span class="source-line-no">3413</span><span id="line-3413"> }).when(mockedCPHost).preBatchMutate(isA(MiniBatchOperationInProgress.class));</span>
<span class="source-line-no">3414</span><span id="line-3414"> ColumnFamilyDescriptorBuilder builder =</span>
<span class="source-line-no">3415</span><span id="line-3415"> ColumnFamilyDescriptorBuilder.newBuilder(COLUMN_FAMILY_BYTES);</span>
<span class="source-line-no">3416</span><span id="line-3416"> ScanInfo info = new ScanInfo(CONF, builder.build(), Long.MAX_VALUE, Long.MAX_VALUE,</span>
<span class="source-line-no">3417</span><span id="line-3417"> region.getCellComparator());</span>
<span class="source-line-no">3418</span><span id="line-3418"> when(mockedCPHost.preFlushScannerOpen(any(HStore.class), any())).thenReturn(info);</span>
<span class="source-line-no">3419</span><span id="line-3419"></span>
<span class="source-line-no">3420</span><span id="line-3420"> when(mockedCPHost.preFlush(any(), any(StoreScanner.class), any()))</span>
<span class="source-line-no">3421</span><span id="line-3421"> .thenAnswer(i -&gt; i.getArgument(1));</span>
<span class="source-line-no">3422</span><span id="line-3422"> region.setCoprocessorHost(mockedCPHost);</span>
<span class="source-line-no">3423</span><span id="line-3423"></span>
<span class="source-line-no">3424</span><span id="line-3424"> region.put(originalPut);</span>
<span class="source-line-no">3425</span><span id="line-3425"> region.setCoprocessorHost(normalCPHost);</span>
<span class="source-line-no">3426</span><span id="line-3426"> final long finalSize = region.getDataInMemoryWithoutWAL();</span>
<span class="source-line-no">3427</span><span id="line-3427"> assertEquals("finalSize:" + finalSize + ", initSize:" + initSize + ", delta:" + delta,</span>
<span class="source-line-no">3428</span><span id="line-3428"> finalSize, initSize + delta);</span>
<span class="source-line-no">3429</span><span id="line-3429"> }</span>
<span class="source-line-no">3430</span><span id="line-3430"></span>
<span class="source-line-no">3431</span><span id="line-3431"> @Test</span>
<span class="source-line-no">3432</span><span id="line-3432"> public void testDeleteColumns_PostInsert() throws IOException, InterruptedException {</span>
<span class="source-line-no">3433</span><span id="line-3433"> Delete delete = new Delete(row);</span>
<span class="source-line-no">3434</span><span id="line-3434"> delete.addColumns(fam1, qual1);</span>
<span class="source-line-no">3435</span><span id="line-3435"> doTestDelete_AndPostInsert(delete);</span>
<span class="source-line-no">3436</span><span id="line-3436"> }</span>
<span class="source-line-no">3437</span><span id="line-3437"></span>
<span class="source-line-no">3438</span><span id="line-3438"> @Test</span>
<span class="source-line-no">3439</span><span id="line-3439"> public void testaddFamily_PostInsert() throws IOException, InterruptedException {</span>
<span class="source-line-no">3440</span><span id="line-3440"> Delete delete = new Delete(row);</span>
<span class="source-line-no">3441</span><span id="line-3441"> delete.addFamily(fam1);</span>
<span class="source-line-no">3442</span><span id="line-3442"> doTestDelete_AndPostInsert(delete);</span>
<span class="source-line-no">3443</span><span id="line-3443"> }</span>
<span class="source-line-no">3444</span><span id="line-3444"></span>
<span class="source-line-no">3445</span><span id="line-3445"> public void doTestDelete_AndPostInsert(Delete delete) throws IOException, InterruptedException {</span>
<span class="source-line-no">3446</span><span id="line-3446"> this.region = initHRegion(tableName, method, CONF, fam1);</span>
<span class="source-line-no">3447</span><span id="line-3447"> EnvironmentEdgeManagerTestHelper.injectEdge(new IncrementingEnvironmentEdge());</span>
<span class="source-line-no">3448</span><span id="line-3448"> Put put = new Put(row);</span>
<span class="source-line-no">3449</span><span id="line-3449"> put.addColumn(fam1, qual1, value1);</span>
<span class="source-line-no">3450</span><span id="line-3450"> region.put(put);</span>
<span class="source-line-no">3451</span><span id="line-3451"></span>
<span class="source-line-no">3452</span><span id="line-3452"> // now delete the value:</span>
<span class="source-line-no">3453</span><span id="line-3453"> region.delete(delete);</span>
<span class="source-line-no">3454</span><span id="line-3454"></span>
<span class="source-line-no">3455</span><span id="line-3455"> // ok put data:</span>
<span class="source-line-no">3456</span><span id="line-3456"> put = new Put(row);</span>
<span class="source-line-no">3457</span><span id="line-3457"> put.addColumn(fam1, qual1, value2);</span>
<span class="source-line-no">3458</span><span id="line-3458"> region.put(put);</span>
<span class="source-line-no">3459</span><span id="line-3459"></span>
<span class="source-line-no">3460</span><span id="line-3460"> // ok get:</span>
<span class="source-line-no">3461</span><span id="line-3461"> Get get = new Get(row);</span>
<span class="source-line-no">3462</span><span id="line-3462"> get.addColumn(fam1, qual1);</span>
<span class="source-line-no">3463</span><span id="line-3463"></span>
<span class="source-line-no">3464</span><span id="line-3464"> Result r = region.get(get);</span>
<span class="source-line-no">3465</span><span id="line-3465"> assertEquals(1, r.size());</span>
<span class="source-line-no">3466</span><span id="line-3466"> assertArrayEquals(value2, r.getValue(fam1, qual1));</span>
<span class="source-line-no">3467</span><span id="line-3467"></span>
<span class="source-line-no">3468</span><span id="line-3468"> // next:</span>
<span class="source-line-no">3469</span><span id="line-3469"> Scan scan = new Scan().withStartRow(row);</span>
<span class="source-line-no">3470</span><span id="line-3470"> scan.addColumn(fam1, qual1);</span>
<span class="source-line-no">3471</span><span id="line-3471"> try (InternalScanner s = region.getScanner(scan)) {</span>
<span class="source-line-no">3472</span><span id="line-3472"> List&lt;Cell&gt; results = new ArrayList&lt;&gt;();</span>
<span class="source-line-no">3473</span><span id="line-3473"> assertEquals(false, s.next(results));</span>
<span class="source-line-no">3474</span><span id="line-3474"> assertEquals(1, results.size());</span>
<span class="source-line-no">3475</span><span id="line-3475"> Cell kv = results.get(0);</span>
<span class="source-line-no">3476</span><span id="line-3476"></span>
<span class="source-line-no">3477</span><span id="line-3477"> assertArrayEquals(value2, CellUtil.cloneValue(kv));</span>
<span class="source-line-no">3478</span><span id="line-3478"> assertArrayEquals(fam1, CellUtil.cloneFamily(kv));</span>
<span class="source-line-no">3479</span><span id="line-3479"> assertArrayEquals(qual1, CellUtil.cloneQualifier(kv));</span>
<span class="source-line-no">3480</span><span id="line-3480"> assertArrayEquals(row, CellUtil.cloneRow(kv));</span>
<span class="source-line-no">3481</span><span id="line-3481"> }</span>
<span class="source-line-no">3482</span><span id="line-3482"> }</span>
<span class="source-line-no">3483</span><span id="line-3483"></span>
<span class="source-line-no">3484</span><span id="line-3484"> @Test</span>
<span class="source-line-no">3485</span><span id="line-3485"> public void testDelete_CheckTimestampUpdated() throws IOException {</span>
<span class="source-line-no">3486</span><span id="line-3486"> byte[] row1 = Bytes.toBytes("row1");</span>
<span class="source-line-no">3487</span><span id="line-3487"> byte[] col1 = Bytes.toBytes("col1");</span>
<span class="source-line-no">3488</span><span id="line-3488"> byte[] col2 = Bytes.toBytes("col2");</span>
<span class="source-line-no">3489</span><span id="line-3489"> byte[] col3 = Bytes.toBytes("col3");</span>
<span class="source-line-no">3490</span><span id="line-3490"></span>
<span class="source-line-no">3491</span><span id="line-3491"> byte[] forUnitTestsOnly = Bytes.toBytes("ForUnitTestsOnly");</span>
<span class="source-line-no">3492</span><span id="line-3492"></span>
<span class="source-line-no">3493</span><span id="line-3493"> // Setting up region</span>
<span class="source-line-no">3494</span><span id="line-3494"> this.region = initHRegion(tableName, method, CONF, fam1);</span>
<span class="source-line-no">3495</span><span id="line-3495"> // Building checkerList</span>
<span class="source-line-no">3496</span><span id="line-3496"> List&lt;Cell&gt; kvs = new ArrayList&lt;&gt;();</span>
<span class="source-line-no">3497</span><span id="line-3497"> kvs.add(new KeyValue(row1, fam1, col1, null));</span>
<span class="source-line-no">3498</span><span id="line-3498"> kvs.add(new KeyValue(row1, fam1, col2, null));</span>
<span class="source-line-no">3499</span><span id="line-3499"> kvs.add(new KeyValue(row1, fam1, col3, null));</span>
<span class="source-line-no">3500</span><span id="line-3500"></span>
<span class="source-line-no">3501</span><span id="line-3501"> NavigableMap&lt;byte[], List&lt;Cell&gt;&gt; deleteMap = new TreeMap&lt;&gt;(Bytes.BYTES_COMPARATOR);</span>
<span class="source-line-no">3502</span><span id="line-3502"> deleteMap.put(fam1, kvs);</span>
<span class="source-line-no">3503</span><span id="line-3503"> region.delete(new Delete(forUnitTestsOnly, HConstants.LATEST_TIMESTAMP, deleteMap));</span>
<span class="source-line-no">3504</span><span id="line-3504"></span>
<span class="source-line-no">3505</span><span id="line-3505"> // extract the key values out the memstore:</span>
<span class="source-line-no">3506</span><span id="line-3506"> // This is kinda hacky, but better than nothing...</span>
<span class="source-line-no">3507</span><span id="line-3507"> long now = EnvironmentEdgeManager.currentTime();</span>
<span class="source-line-no">3508</span><span id="line-3508"> AbstractMemStore memstore = (AbstractMemStore) region.getStore(fam1).memstore;</span>
<span class="source-line-no">3509</span><span id="line-3509"> Cell firstCell = memstore.getActive().first();</span>
<span class="source-line-no">3510</span><span id="line-3510"> assertTrue(firstCell.getTimestamp() &lt;= now);</span>
<span class="source-line-no">3511</span><span id="line-3511"> now = firstCell.getTimestamp();</span>
<span class="source-line-no">3512</span><span id="line-3512"> for (Cell cell : memstore.getActive().getCellSet()) {</span>
<span class="source-line-no">3513</span><span id="line-3513"> assertTrue(cell.getTimestamp() &lt;= now);</span>
<span class="source-line-no">3514</span><span id="line-3514"> now = cell.getTimestamp();</span>
<span class="source-line-no">3515</span><span id="line-3515"> }</span>
<span class="source-line-no">3516</span><span id="line-3516"> }</span>
<span class="source-line-no">3517</span><span id="line-3517"></span>
<span class="source-line-no">3518</span><span id="line-3518"> // ////////////////////////////////////////////////////////////////////////////</span>
<span class="source-line-no">3519</span><span id="line-3519"> // Get tests</span>
<span class="source-line-no">3520</span><span id="line-3520"> // ////////////////////////////////////////////////////////////////////////////</span>
<span class="source-line-no">3521</span><span id="line-3521"> @Test</span>
<span class="source-line-no">3522</span><span id="line-3522"> public void testGet_FamilyChecker() throws IOException {</span>
<span class="source-line-no">3523</span><span id="line-3523"> byte[] row1 = Bytes.toBytes("row1");</span>
<span class="source-line-no">3524</span><span id="line-3524"> byte[] fam1 = Bytes.toBytes("fam1");</span>
<span class="source-line-no">3525</span><span id="line-3525"> byte[] fam2 = Bytes.toBytes("False");</span>
<span class="source-line-no">3526</span><span id="line-3526"> byte[] col1 = Bytes.toBytes("col1");</span>
<span class="source-line-no">3527</span><span id="line-3527"></span>
<span class="source-line-no">3528</span><span id="line-3528"> // Setting up region</span>
<span class="source-line-no">3529</span><span id="line-3529"> this.region = initHRegion(tableName, method, CONF, fam1);</span>
<span class="source-line-no">3530</span><span id="line-3530"> Get get = new Get(row1);</span>
<span class="source-line-no">3531</span><span id="line-3531"> get.addColumn(fam2, col1);</span>
<span class="source-line-no">3532</span><span id="line-3532"></span>
<span class="source-line-no">3533</span><span id="line-3533"> // Test</span>
<span class="source-line-no">3534</span><span id="line-3534"> try {</span>
<span class="source-line-no">3535</span><span id="line-3535"> region.get(get);</span>
<span class="source-line-no">3536</span><span id="line-3536"> fail("Expecting DoNotRetryIOException in get but did not get any");</span>
<span class="source-line-no">3537</span><span id="line-3537"> } catch (org.apache.hadoop.hbase.DoNotRetryIOException e) {</span>
<span class="source-line-no">3538</span><span id="line-3538"> LOG.info("Got expected DoNotRetryIOException successfully");</span>
<span class="source-line-no">3539</span><span id="line-3539"> }</span>
<span class="source-line-no">3540</span><span id="line-3540"> }</span>
<span class="source-line-no">3541</span><span id="line-3541"></span>
<span class="source-line-no">3542</span><span id="line-3542"> @Test</span>
<span class="source-line-no">3543</span><span id="line-3543"> public void testGet_Basic() throws IOException {</span>
<span class="source-line-no">3544</span><span id="line-3544"> byte[] row1 = Bytes.toBytes("row1");</span>
<span class="source-line-no">3545</span><span id="line-3545"> byte[] fam1 = Bytes.toBytes("fam1");</span>
<span class="source-line-no">3546</span><span id="line-3546"> byte[] col1 = Bytes.toBytes("col1");</span>
<span class="source-line-no">3547</span><span id="line-3547"> byte[] col2 = Bytes.toBytes("col2");</span>
<span class="source-line-no">3548</span><span id="line-3548"> byte[] col3 = Bytes.toBytes("col3");</span>
<span class="source-line-no">3549</span><span id="line-3549"> byte[] col4 = Bytes.toBytes("col4");</span>
<span class="source-line-no">3550</span><span id="line-3550"> byte[] col5 = Bytes.toBytes("col5");</span>
<span class="source-line-no">3551</span><span id="line-3551"></span>
<span class="source-line-no">3552</span><span id="line-3552"> // Setting up region</span>
<span class="source-line-no">3553</span><span id="line-3553"> this.region = initHRegion(tableName, method, CONF, fam1);</span>
<span class="source-line-no">3554</span><span id="line-3554"> // Add to memstore</span>
<span class="source-line-no">3555</span><span id="line-3555"> Put put = new Put(row1);</span>
<span class="source-line-no">3556</span><span id="line-3556"> put.addColumn(fam1, col1, null);</span>
<span class="source-line-no">3557</span><span id="line-3557"> put.addColumn(fam1, col2, null);</span>
<span class="source-line-no">3558</span><span id="line-3558"> put.addColumn(fam1, col3, null);</span>
<span class="source-line-no">3559</span><span id="line-3559"> put.addColumn(fam1, col4, null);</span>
<span class="source-line-no">3560</span><span id="line-3560"> put.addColumn(fam1, col5, null);</span>
<span class="source-line-no">3561</span><span id="line-3561"> region.put(put);</span>
<span class="source-line-no">3562</span><span id="line-3562"></span>
<span class="source-line-no">3563</span><span id="line-3563"> Get get = new Get(row1);</span>
<span class="source-line-no">3564</span><span id="line-3564"> get.addColumn(fam1, col2);</span>
<span class="source-line-no">3565</span><span id="line-3565"> get.addColumn(fam1, col4);</span>
<span class="source-line-no">3566</span><span id="line-3566"> // Expected result</span>
<span class="source-line-no">3567</span><span id="line-3567"> KeyValue kv1 = new KeyValue(row1, fam1, col2);</span>
<span class="source-line-no">3568</span><span id="line-3568"> KeyValue kv2 = new KeyValue(row1, fam1, col4);</span>
<span class="source-line-no">3569</span><span id="line-3569"> KeyValue[] expected = { kv1, kv2 };</span>
<span class="source-line-no">3570</span><span id="line-3570"></span>
<span class="source-line-no">3571</span><span id="line-3571"> // Test</span>
<span class="source-line-no">3572</span><span id="line-3572"> Result res = region.get(get);</span>
<span class="source-line-no">3573</span><span id="line-3573"> assertEquals(expected.length, res.size());</span>
<span class="source-line-no">3574</span><span id="line-3574"> for (int i = 0; i &lt; res.size(); i++) {</span>
<span class="source-line-no">3575</span><span id="line-3575"> assertTrue(CellUtil.matchingRows(expected[i], res.rawCells()[i]));</span>
<span class="source-line-no">3576</span><span id="line-3576"> assertTrue(CellUtil.matchingFamily(expected[i], res.rawCells()[i]));</span>
<span class="source-line-no">3577</span><span id="line-3577"> assertTrue(CellUtil.matchingQualifier(expected[i], res.rawCells()[i]));</span>
<span class="source-line-no">3578</span><span id="line-3578"> }</span>
<span class="source-line-no">3579</span><span id="line-3579"></span>
<span class="source-line-no">3580</span><span id="line-3580"> // Test using a filter on a Get</span>
<span class="source-line-no">3581</span><span id="line-3581"> Get g = new Get(row1);</span>
<span class="source-line-no">3582</span><span id="line-3582"> final int count = 2;</span>
<span class="source-line-no">3583</span><span id="line-3583"> g.setFilter(new ColumnCountGetFilter(count));</span>
<span class="source-line-no">3584</span><span id="line-3584"> res = region.get(g);</span>
<span class="source-line-no">3585</span><span id="line-3585"> assertEquals(count, res.size());</span>
<span class="source-line-no">3586</span><span id="line-3586"> }</span>
<span class="source-line-no">3587</span><span id="line-3587"></span>
<span class="source-line-no">3588</span><span id="line-3588"> @Test</span>
<span class="source-line-no">3589</span><span id="line-3589"> public void testGet_Empty() throws IOException {</span>
<span class="source-line-no">3590</span><span id="line-3590"> byte[] row = Bytes.toBytes("row");</span>
<span class="source-line-no">3591</span><span id="line-3591"> byte[] fam = Bytes.toBytes("fam");</span>
<span class="source-line-no">3592</span><span id="line-3592"></span>
<span class="source-line-no">3593</span><span id="line-3593"> this.region = initHRegion(tableName, method, CONF, fam);</span>
<span class="source-line-no">3594</span><span id="line-3594"> Get get = new Get(row);</span>
<span class="source-line-no">3595</span><span id="line-3595"> get.addFamily(fam);</span>
<span class="source-line-no">3596</span><span id="line-3596"> Result r = region.get(get);</span>
<span class="source-line-no">3597</span><span id="line-3597"></span>
<span class="source-line-no">3598</span><span id="line-3598"> assertTrue(r.isEmpty());</span>
<span class="source-line-no">3599</span><span id="line-3599"> }</span>
<span class="source-line-no">3600</span><span id="line-3600"></span>
<span class="source-line-no">3601</span><span id="line-3601"> @Test</span>
<span class="source-line-no">3602</span><span id="line-3602"> public void testGetWithFilter() throws IOException, InterruptedException {</span>
<span class="source-line-no">3603</span><span id="line-3603"> byte[] row1 = Bytes.toBytes("row1");</span>
<span class="source-line-no">3604</span><span id="line-3604"> byte[] fam1 = Bytes.toBytes("fam1");</span>
<span class="source-line-no">3605</span><span id="line-3605"> byte[] col1 = Bytes.toBytes("col1");</span>
<span class="source-line-no">3606</span><span id="line-3606"> byte[] value1 = Bytes.toBytes("value1");</span>
<span class="source-line-no">3607</span><span id="line-3607"> byte[] value2 = Bytes.toBytes("value2");</span>
<span class="source-line-no">3608</span><span id="line-3608"></span>
<span class="source-line-no">3609</span><span id="line-3609"> final int maxVersions = 3;</span>
<span class="source-line-no">3610</span><span id="line-3610"> TableDescriptor tableDescriptor =</span>
<span class="source-line-no">3611</span><span id="line-3611"> TableDescriptorBuilder.newBuilder(TableName.valueOf("testFilterAndColumnTracker"))</span>
<span class="source-line-no">3612</span><span id="line-3612"> .setColumnFamily(</span>
<span class="source-line-no">3613</span><span id="line-3613"> ColumnFamilyDescriptorBuilder.newBuilder(fam1).setMaxVersions(maxVersions).build())</span>
<span class="source-line-no">3614</span><span id="line-3614"> .build();</span>
<span class="source-line-no">3615</span><span id="line-3615"> ChunkCreator.initialize(MemStoreLAB.CHUNK_SIZE_DEFAULT, false, 0, 0, 0, null,</span>
<span class="source-line-no">3616</span><span id="line-3616"> MemStoreLAB.INDEX_CHUNK_SIZE_PERCENTAGE_DEFAULT);</span>
<span class="source-line-no">3617</span><span id="line-3617"> RegionInfo info = RegionInfoBuilder.newBuilder(tableDescriptor.getTableName()).build();</span>
<span class="source-line-no">3618</span><span id="line-3618"> Path logDir = TEST_UTIL.getDataTestDirOnTestFS(method + ".log");</span>
<span class="source-line-no">3619</span><span id="line-3619"> final WAL wal = HBaseTestingUtil.createWal(TEST_UTIL.getConfiguration(), logDir, info);</span>
<span class="source-line-no">3620</span><span id="line-3620"> this.region = TEST_UTIL.createLocalHRegion(info, CONF, tableDescriptor, wal);</span>
<span class="source-line-no">3621</span><span id="line-3621"></span>
<span class="source-line-no">3622</span><span id="line-3622"> // Put 4 version to memstore</span>
<span class="source-line-no">3623</span><span id="line-3623"> long ts = 0;</span>
<span class="source-line-no">3624</span><span id="line-3624"> Put put = new Put(row1, ts);</span>
<span class="source-line-no">3625</span><span id="line-3625"> put.addColumn(fam1, col1, value1);</span>
<span class="source-line-no">3626</span><span id="line-3626"> region.put(put);</span>
<span class="source-line-no">3627</span><span id="line-3627"> put = new Put(row1, ts + 1);</span>
<span class="source-line-no">3628</span><span id="line-3628"> put.addColumn(fam1, col1, Bytes.toBytes("filter1"));</span>
<span class="source-line-no">3629</span><span id="line-3629"> region.put(put);</span>
<span class="source-line-no">3630</span><span id="line-3630"> put = new Put(row1, ts + 2);</span>
<span class="source-line-no">3631</span><span id="line-3631"> put.addColumn(fam1, col1, Bytes.toBytes("filter2"));</span>
<span class="source-line-no">3632</span><span id="line-3632"> region.put(put);</span>
<span class="source-line-no">3633</span><span id="line-3633"> put = new Put(row1, ts + 3);</span>
<span class="source-line-no">3634</span><span id="line-3634"> put.addColumn(fam1, col1, value2);</span>
<span class="source-line-no">3635</span><span id="line-3635"> region.put(put);</span>
<span class="source-line-no">3636</span><span id="line-3636"></span>
<span class="source-line-no">3637</span><span id="line-3637"> Get get = new Get(row1);</span>
<span class="source-line-no">3638</span><span id="line-3638"> get.readAllVersions();</span>
<span class="source-line-no">3639</span><span id="line-3639"> Result res = region.get(get);</span>
<span class="source-line-no">3640</span><span id="line-3640"> // Get 3 versions, the oldest version has gone from user view</span>
<span class="source-line-no">3641</span><span id="line-3641"> assertEquals(maxVersions, res.size());</span>
<span class="source-line-no">3642</span><span id="line-3642"></span>
<span class="source-line-no">3643</span><span id="line-3643"> get.setFilter(new ValueFilter(CompareOperator.EQUAL, new SubstringComparator("value")));</span>
<span class="source-line-no">3644</span><span id="line-3644"> res = region.get(get);</span>
<span class="source-line-no">3645</span><span id="line-3645"> // When use value filter, the oldest version should still gone from user view and it</span>
<span class="source-line-no">3646</span><span id="line-3646"> // should only return one key vaule</span>
<span class="source-line-no">3647</span><span id="line-3647"> assertEquals(1, res.size());</span>
<span class="source-line-no">3648</span><span id="line-3648"> assertTrue(CellUtil.matchingValue(new KeyValue(row1, fam1, col1, value2), res.rawCells()[0]));</span>
<span class="source-line-no">3649</span><span id="line-3649"> assertEquals(ts + 3, res.rawCells()[0].getTimestamp());</span>
<span class="source-line-no">3650</span><span id="line-3650"></span>
<span class="source-line-no">3651</span><span id="line-3651"> region.flush(true);</span>
<span class="source-line-no">3652</span><span id="line-3652"> region.compact(true);</span>
<span class="source-line-no">3653</span><span id="line-3653"> Thread.sleep(1000);</span>
<span class="source-line-no">3654</span><span id="line-3654"> res = region.get(get);</span>
<span class="source-line-no">3655</span><span id="line-3655"> // After flush and compact, the result should be consistent with previous result</span>
<span class="source-line-no">3656</span><span id="line-3656"> assertEquals(1, res.size());</span>
<span class="source-line-no">3657</span><span id="line-3657"> assertTrue(CellUtil.matchingValue(new KeyValue(row1, fam1, col1, value2), res.rawCells()[0]));</span>
<span class="source-line-no">3658</span><span id="line-3658"> }</span>
<span class="source-line-no">3659</span><span id="line-3659"></span>
<span class="source-line-no">3660</span><span id="line-3660"> // ////////////////////////////////////////////////////////////////////////////</span>
<span class="source-line-no">3661</span><span id="line-3661"> // Scanner tests</span>
<span class="source-line-no">3662</span><span id="line-3662"> // ////////////////////////////////////////////////////////////////////////////</span>
<span class="source-line-no">3663</span><span id="line-3663"> @Test</span>
<span class="source-line-no">3664</span><span id="line-3664"> public void testGetScanner_WithOkFamilies() throws IOException {</span>
<span class="source-line-no">3665</span><span id="line-3665"> byte[] fam1 = Bytes.toBytes("fam1");</span>
<span class="source-line-no">3666</span><span id="line-3666"> byte[] fam2 = Bytes.toBytes("fam2");</span>
<span class="source-line-no">3667</span><span id="line-3667"></span>
<span class="source-line-no">3668</span><span id="line-3668"> byte[][] families = { fam1, fam2 };</span>
<span class="source-line-no">3669</span><span id="line-3669"></span>
<span class="source-line-no">3670</span><span id="line-3670"> // Setting up region</span>
<span class="source-line-no">3671</span><span id="line-3671"> this.region = initHRegion(tableName, method, CONF, families);</span>
<span class="source-line-no">3672</span><span id="line-3672"> Scan scan = new Scan();</span>
<span class="source-line-no">3673</span><span id="line-3673"> scan.addFamily(fam1);</span>
<span class="source-line-no">3674</span><span id="line-3674"> scan.addFamily(fam2);</span>
<span class="source-line-no">3675</span><span id="line-3675"> region.getScanner(scan).close();</span>
<span class="source-line-no">3676</span><span id="line-3676"> }</span>
<span class="source-line-no">3677</span><span id="line-3677"></span>
<span class="source-line-no">3678</span><span id="line-3678"> @Test</span>
<span class="source-line-no">3679</span><span id="line-3679"> public void testGetScanner_WithNotOkFamilies() throws IOException {</span>
<span class="source-line-no">3680</span><span id="line-3680"> byte[] fam1 = Bytes.toBytes("fam1");</span>
<span class="source-line-no">3681</span><span id="line-3681"> byte[] fam2 = Bytes.toBytes("fam2");</span>
<span class="source-line-no">3682</span><span id="line-3682"></span>
<span class="source-line-no">3683</span><span id="line-3683"> byte[][] families = { fam1 };</span>
<span class="source-line-no">3684</span><span id="line-3684"></span>
<span class="source-line-no">3685</span><span id="line-3685"> // Setting up region</span>
<span class="source-line-no">3686</span><span id="line-3686"> this.region = initHRegion(tableName, method, CONF, families);</span>
<span class="source-line-no">3687</span><span id="line-3687"> Scan scan = new Scan();</span>
<span class="source-line-no">3688</span><span id="line-3688"> scan.addFamily(fam2);</span>
<span class="source-line-no">3689</span><span id="line-3689"> assertThrows(NoSuchColumnFamilyException.class, () -&gt; region.getScanner(scan));</span>
<span class="source-line-no">3690</span><span id="line-3690"> }</span>
<span class="source-line-no">3691</span><span id="line-3691"></span>
<span class="source-line-no">3692</span><span id="line-3692"> @Test</span>
<span class="source-line-no">3693</span><span id="line-3693"> public void testGetScanner_WithNoFamilies() throws IOException {</span>
<span class="source-line-no">3694</span><span id="line-3694"> byte[] row1 = Bytes.toBytes("row1");</span>
<span class="source-line-no">3695</span><span id="line-3695"> byte[] fam1 = Bytes.toBytes("fam1");</span>
<span class="source-line-no">3696</span><span id="line-3696"> byte[] fam2 = Bytes.toBytes("fam2");</span>
<span class="source-line-no">3697</span><span id="line-3697"> byte[] fam3 = Bytes.toBytes("fam3");</span>
<span class="source-line-no">3698</span><span id="line-3698"> byte[] fam4 = Bytes.toBytes("fam4");</span>
<span class="source-line-no">3699</span><span id="line-3699"></span>
<span class="source-line-no">3700</span><span id="line-3700"> byte[][] families = { fam1, fam2, fam3, fam4 };</span>
<span class="source-line-no">3701</span><span id="line-3701"></span>
<span class="source-line-no">3702</span><span id="line-3702"> // Setting up region</span>
<span class="source-line-no">3703</span><span id="line-3703"> this.region = initHRegion(tableName, method, CONF, families);</span>
<span class="source-line-no">3704</span><span id="line-3704"> // Putting data in Region</span>
<span class="source-line-no">3705</span><span id="line-3705"> Put put = new Put(row1);</span>
<span class="source-line-no">3706</span><span id="line-3706"> put.addColumn(fam1, null, null);</span>
<span class="source-line-no">3707</span><span id="line-3707"> put.addColumn(fam2, null, null);</span>
<span class="source-line-no">3708</span><span id="line-3708"> put.addColumn(fam3, null, null);</span>
<span class="source-line-no">3709</span><span id="line-3709"> put.addColumn(fam4, null, null);</span>
<span class="source-line-no">3710</span><span id="line-3710"> region.put(put);</span>
<span class="source-line-no">3711</span><span id="line-3711"></span>
<span class="source-line-no">3712</span><span id="line-3712"> Scan scan = null;</span>
<span class="source-line-no">3713</span><span id="line-3713"></span>
<span class="source-line-no">3714</span><span id="line-3714"> // Testing to see how many scanners that is produced by getScanner, starting with known number,</span>
<span class="source-line-no">3715</span><span id="line-3715"> // 2 - current = 1</span>
<span class="source-line-no">3716</span><span id="line-3716"> scan = new Scan();</span>
<span class="source-line-no">3717</span><span id="line-3717"> scan.addFamily(fam2);</span>
<span class="source-line-no">3718</span><span id="line-3718"> scan.addFamily(fam4);</span>
<span class="source-line-no">3719</span><span id="line-3719"> try (RegionScannerImpl is = region.getScanner(scan)) {</span>
<span class="source-line-no">3720</span><span id="line-3720"> assertEquals(1, is.storeHeap.getHeap().size());</span>
<span class="source-line-no">3721</span><span id="line-3721"> }</span>
<span class="source-line-no">3722</span><span id="line-3722"></span>
<span class="source-line-no">3723</span><span id="line-3723"> scan = new Scan();</span>
<span class="source-line-no">3724</span><span id="line-3724"> try (RegionScannerImpl is = region.getScanner(scan)) {</span>
<span class="source-line-no">3725</span><span id="line-3725"> assertEquals(families.length - 1, is.storeHeap.getHeap().size());</span>
<span class="source-line-no">3726</span><span id="line-3726"> }</span>
<span class="source-line-no">3727</span><span id="line-3727"> }</span>
<span class="source-line-no">3728</span><span id="line-3728"></span>
<span class="source-line-no">3729</span><span id="line-3729"> /**</span>
<span class="source-line-no">3730</span><span id="line-3730"> * This method tests https://issues.apache.org/jira/browse/HBASE-2516.</span>
<span class="source-line-no">3731</span><span id="line-3731"> */</span>
<span class="source-line-no">3732</span><span id="line-3732"> @Test</span>
<span class="source-line-no">3733</span><span id="line-3733"> public void testGetScanner_WithRegionClosed() throws IOException {</span>
<span class="source-line-no">3734</span><span id="line-3734"> byte[] fam1 = Bytes.toBytes("fam1");</span>
<span class="source-line-no">3735</span><span id="line-3735"> byte[] fam2 = Bytes.toBytes("fam2");</span>
<span class="source-line-no">3736</span><span id="line-3736"></span>
<span class="source-line-no">3737</span><span id="line-3737"> byte[][] families = { fam1, fam2 };</span>
<span class="source-line-no">3738</span><span id="line-3738"></span>
<span class="source-line-no">3739</span><span id="line-3739"> // Setting up region</span>
<span class="source-line-no">3740</span><span id="line-3740"> region = initHRegion(tableName, method, CONF, families);</span>
<span class="source-line-no">3741</span><span id="line-3741"> region.closed.set(true);</span>
<span class="source-line-no">3742</span><span id="line-3742"> try {</span>
<span class="source-line-no">3743</span><span id="line-3743"> assertThrows(NotServingRegionException.class, () -&gt; region.getScanner(null));</span>
<span class="source-line-no">3744</span><span id="line-3744"> } finally {</span>
<span class="source-line-no">3745</span><span id="line-3745"> // so we can close the region in tearDown</span>
<span class="source-line-no">3746</span><span id="line-3746"> region.closed.set(false);</span>
<span class="source-line-no">3747</span><span id="line-3747"> }</span>
<span class="source-line-no">3748</span><span id="line-3748"> }</span>
<span class="source-line-no">3749</span><span id="line-3749"></span>
<span class="source-line-no">3750</span><span id="line-3750"> @Test</span>
<span class="source-line-no">3751</span><span id="line-3751"> public void testRegionScanner_Next() throws IOException {</span>
<span class="source-line-no">3752</span><span id="line-3752"> byte[] row1 = Bytes.toBytes("row1");</span>
<span class="source-line-no">3753</span><span id="line-3753"> byte[] row2 = Bytes.toBytes("row2");</span>
<span class="source-line-no">3754</span><span id="line-3754"> byte[] fam1 = Bytes.toBytes("fam1");</span>
<span class="source-line-no">3755</span><span id="line-3755"> byte[] fam2 = Bytes.toBytes("fam2");</span>
<span class="source-line-no">3756</span><span id="line-3756"> byte[] fam3 = Bytes.toBytes("fam3");</span>
<span class="source-line-no">3757</span><span id="line-3757"> byte[] fam4 = Bytes.toBytes("fam4");</span>
<span class="source-line-no">3758</span><span id="line-3758"></span>
<span class="source-line-no">3759</span><span id="line-3759"> byte[][] families = { fam1, fam2, fam3, fam4 };</span>
<span class="source-line-no">3760</span><span id="line-3760"> long ts = EnvironmentEdgeManager.currentTime();</span>
<span class="source-line-no">3761</span><span id="line-3761"></span>
<span class="source-line-no">3762</span><span id="line-3762"> // Setting up region</span>
<span class="source-line-no">3763</span><span id="line-3763"> this.region = initHRegion(tableName, method, CONF, families);</span>
<span class="source-line-no">3764</span><span id="line-3764"> // Putting data in Region</span>
<span class="source-line-no">3765</span><span id="line-3765"> Put put = null;</span>
<span class="source-line-no">3766</span><span id="line-3766"> put = new Put(row1);</span>
<span class="source-line-no">3767</span><span id="line-3767"> put.addColumn(fam1, (byte[]) null, ts, null);</span>
<span class="source-line-no">3768</span><span id="line-3768"> put.addColumn(fam2, (byte[]) null, ts, null);</span>
<span class="source-line-no">3769</span><span id="line-3769"> put.addColumn(fam3, (byte[]) null, ts, null);</span>
<span class="source-line-no">3770</span><span id="line-3770"> put.addColumn(fam4, (byte[]) null, ts, null);</span>
<span class="source-line-no">3771</span><span id="line-3771"> region.put(put);</span>
<span class="source-line-no">3772</span><span id="line-3772"></span>
<span class="source-line-no">3773</span><span id="line-3773"> put = new Put(row2);</span>
<span class="source-line-no">3774</span><span id="line-3774"> put.addColumn(fam1, (byte[]) null, ts, null);</span>
<span class="source-line-no">3775</span><span id="line-3775"> put.addColumn(fam2, (byte[]) null, ts, null);</span>
<span class="source-line-no">3776</span><span id="line-3776"> put.addColumn(fam3, (byte[]) null, ts, null);</span>
<span class="source-line-no">3777</span><span id="line-3777"> put.addColumn(fam4, (byte[]) null, ts, null);</span>
<span class="source-line-no">3778</span><span id="line-3778"> region.put(put);</span>
<span class="source-line-no">3779</span><span id="line-3779"></span>
<span class="source-line-no">3780</span><span id="line-3780"> Scan scan = new Scan();</span>
<span class="source-line-no">3781</span><span id="line-3781"> scan.addFamily(fam2);</span>
<span class="source-line-no">3782</span><span id="line-3782"> scan.addFamily(fam4);</span>
<span class="source-line-no">3783</span><span id="line-3783"> try (InternalScanner is = region.getScanner(scan)) {</span>
<span class="source-line-no">3784</span><span id="line-3784"> List&lt;ExtendedCell&gt; res = null;</span>
<span class="source-line-no">3785</span><span id="line-3785"></span>
<span class="source-line-no">3786</span><span id="line-3786"> // Result 1</span>
<span class="source-line-no">3787</span><span id="line-3787"> List&lt;ExtendedCell&gt; expected1 = new ArrayList&lt;&gt;();</span>
<span class="source-line-no">3788</span><span id="line-3788"> expected1.add(new KeyValue(row1, fam2, null, ts, KeyValue.Type.Put, null));</span>
<span class="source-line-no">3789</span><span id="line-3789"> expected1.add(new KeyValue(row1, fam4, null, ts, KeyValue.Type.Put, null));</span>
<span class="source-line-no">3790</span><span id="line-3790"></span>
<span class="source-line-no">3791</span><span id="line-3791"> res = new ArrayList&lt;&gt;();</span>
<span class="source-line-no">3792</span><span id="line-3792"> is.next((List) res);</span>
<span class="source-line-no">3793</span><span id="line-3793"> for (int i = 0; i &lt; res.size(); i++) {</span>
<span class="source-line-no">3794</span><span id="line-3794"> assertTrue(PrivateCellUtil.equalsIgnoreMvccVersion(expected1.get(i), res.get(i)));</span>
<span class="source-line-no">3795</span><span id="line-3795"> }</span>
<span class="source-line-no">3796</span><span id="line-3796"></span>
<span class="source-line-no">3797</span><span id="line-3797"> // Result 2</span>
<span class="source-line-no">3798</span><span id="line-3798"> List&lt;ExtendedCell&gt; expected2 = new ArrayList&lt;&gt;();</span>
<span class="source-line-no">3799</span><span id="line-3799"> expected2.add(new KeyValue(row2, fam2, null, ts, KeyValue.Type.Put, null));</span>
<span class="source-line-no">3800</span><span id="line-3800"> expected2.add(new KeyValue(row2, fam4, null, ts, KeyValue.Type.Put, null));</span>
<span class="source-line-no">3801</span><span id="line-3801"></span>
<span class="source-line-no">3802</span><span id="line-3802"> res = new ArrayList&lt;&gt;();</span>
<span class="source-line-no">3803</span><span id="line-3803"> is.next((List) res);</span>
<span class="source-line-no">3804</span><span id="line-3804"> for (int i = 0; i &lt; res.size(); i++) {</span>
<span class="source-line-no">3805</span><span id="line-3805"> assertTrue(PrivateCellUtil.equalsIgnoreMvccVersion(expected2.get(i), res.get(i)));</span>
<span class="source-line-no">3806</span><span id="line-3806"> }</span>
<span class="source-line-no">3807</span><span id="line-3807"> }</span>
<span class="source-line-no">3808</span><span id="line-3808"> }</span>
<span class="source-line-no">3809</span><span id="line-3809"></span>
<span class="source-line-no">3810</span><span id="line-3810"> @Test</span>
<span class="source-line-no">3811</span><span id="line-3811"> public void testScanner_ExplicitColumns_FromMemStore_EnforceVersions() throws IOException {</span>
<span class="source-line-no">3812</span><span id="line-3812"> byte[] row1 = Bytes.toBytes("row1");</span>
<span class="source-line-no">3813</span><span id="line-3813"> byte[] qf1 = Bytes.toBytes("qualifier1");</span>
<span class="source-line-no">3814</span><span id="line-3814"> byte[] qf2 = Bytes.toBytes("qualifier2");</span>
<span class="source-line-no">3815</span><span id="line-3815"> byte[] fam1 = Bytes.toBytes("fam1");</span>
<span class="source-line-no">3816</span><span id="line-3816"> byte[][] families = { fam1 };</span>
<span class="source-line-no">3817</span><span id="line-3817"></span>
<span class="source-line-no">3818</span><span id="line-3818"> long ts1 = EnvironmentEdgeManager.currentTime();</span>
<span class="source-line-no">3819</span><span id="line-3819"> long ts2 = ts1 + 1;</span>
<span class="source-line-no">3820</span><span id="line-3820"> long ts3 = ts1 + 2;</span>
<span class="source-line-no">3821</span><span id="line-3821"></span>
<span class="source-line-no">3822</span><span id="line-3822"> // Setting up region</span>
<span class="source-line-no">3823</span><span id="line-3823"> this.region = initHRegion(tableName, method, CONF, families);</span>
<span class="source-line-no">3824</span><span id="line-3824"> // Putting data in Region</span>
<span class="source-line-no">3825</span><span id="line-3825"> Put put = null;</span>
<span class="source-line-no">3826</span><span id="line-3826"> KeyValue kv13 = new KeyValue(row1, fam1, qf1, ts3, KeyValue.Type.Put, null);</span>
<span class="source-line-no">3827</span><span id="line-3827"> KeyValue kv12 = new KeyValue(row1, fam1, qf1, ts2, KeyValue.Type.Put, null);</span>
<span class="source-line-no">3828</span><span id="line-3828"> KeyValue kv11 = new KeyValue(row1, fam1, qf1, ts1, KeyValue.Type.Put, null);</span>
<span class="source-line-no">3829</span><span id="line-3829"></span>
<span class="source-line-no">3830</span><span id="line-3830"> KeyValue kv23 = new KeyValue(row1, fam1, qf2, ts3, KeyValue.Type.Put, null);</span>
<span class="source-line-no">3831</span><span id="line-3831"> KeyValue kv22 = new KeyValue(row1, fam1, qf2, ts2, KeyValue.Type.Put, null);</span>
<span class="source-line-no">3832</span><span id="line-3832"> KeyValue kv21 = new KeyValue(row1, fam1, qf2, ts1, KeyValue.Type.Put, null);</span>
<span class="source-line-no">3833</span><span id="line-3833"></span>
<span class="source-line-no">3834</span><span id="line-3834"> put = new Put(row1);</span>
<span class="source-line-no">3835</span><span id="line-3835"> put.add(kv13);</span>
<span class="source-line-no">3836</span><span id="line-3836"> put.add(kv12);</span>
<span class="source-line-no">3837</span><span id="line-3837"> put.add(kv11);</span>
<span class="source-line-no">3838</span><span id="line-3838"> put.add(kv23);</span>
<span class="source-line-no">3839</span><span id="line-3839"> put.add(kv22);</span>
<span class="source-line-no">3840</span><span id="line-3840"> put.add(kv21);</span>
<span class="source-line-no">3841</span><span id="line-3841"> region.put(put);</span>
<span class="source-line-no">3842</span><span id="line-3842"></span>
<span class="source-line-no">3843</span><span id="line-3843"> // Expected</span>
<span class="source-line-no">3844</span><span id="line-3844"> List&lt;Cell&gt; expected = new ArrayList&lt;&gt;();</span>
<span class="source-line-no">3845</span><span id="line-3845"> expected.add(kv13);</span>
<span class="source-line-no">3846</span><span id="line-3846"> expected.add(kv12);</span>
<span class="source-line-no">3847</span><span id="line-3847"></span>
<span class="source-line-no">3848</span><span id="line-3848"> Scan scan = new Scan().withStartRow(row1);</span>
<span class="source-line-no">3849</span><span id="line-3849"> scan.addColumn(fam1, qf1);</span>
<span class="source-line-no">3850</span><span id="line-3850"> scan.readVersions(MAX_VERSIONS);</span>
<span class="source-line-no">3851</span><span id="line-3851"> List&lt;Cell&gt; actual = new ArrayList&lt;&gt;();</span>
<span class="source-line-no">3852</span><span id="line-3852"> try (InternalScanner scanner = region.getScanner(scan)) {</span>
<span class="source-line-no">3853</span><span id="line-3853"> boolean hasNext = scanner.next(actual);</span>
<span class="source-line-no">3854</span><span id="line-3854"> assertEquals(false, hasNext);</span>
<span class="source-line-no">3855</span><span id="line-3855"></span>
<span class="source-line-no">3856</span><span id="line-3856"> // Verify result</span>
<span class="source-line-no">3857</span><span id="line-3857"> for (int i = 0; i &lt; expected.size(); i++) {</span>
<span class="source-line-no">3858</span><span id="line-3858"> assertEquals(expected.get(i), actual.get(i));</span>
<span class="source-line-no">3859</span><span id="line-3859"> }</span>
<span class="source-line-no">3860</span><span id="line-3860"> }</span>
<span class="source-line-no">3861</span><span id="line-3861"> }</span>
<span class="source-line-no">3862</span><span id="line-3862"></span>
<span class="source-line-no">3863</span><span id="line-3863"> @Test</span>
<span class="source-line-no">3864</span><span id="line-3864"> public void testScanner_ExplicitColumns_FromFilesOnly_EnforceVersions() throws IOException {</span>
<span class="source-line-no">3865</span><span id="line-3865"> byte[] row1 = Bytes.toBytes("row1");</span>
<span class="source-line-no">3866</span><span id="line-3866"> byte[] qf1 = Bytes.toBytes("qualifier1");</span>
<span class="source-line-no">3867</span><span id="line-3867"> byte[] qf2 = Bytes.toBytes("qualifier2");</span>
<span class="source-line-no">3868</span><span id="line-3868"> byte[] fam1 = Bytes.toBytes("fam1");</span>
<span class="source-line-no">3869</span><span id="line-3869"> byte[][] families = { fam1 };</span>
<span class="source-line-no">3870</span><span id="line-3870"></span>
<span class="source-line-no">3871</span><span id="line-3871"> long ts1 = 1;</span>
<span class="source-line-no">3872</span><span id="line-3872"> long ts2 = ts1 + 1;</span>
<span class="source-line-no">3873</span><span id="line-3873"> long ts3 = ts1 + 2;</span>
<span class="source-line-no">3874</span><span id="line-3874"></span>
<span class="source-line-no">3875</span><span id="line-3875"> // Setting up region</span>
<span class="source-line-no">3876</span><span id="line-3876"> this.region = initHRegion(tableName, method, CONF, families);</span>
<span class="source-line-no">3877</span><span id="line-3877"> // Putting data in Region</span>
<span class="source-line-no">3878</span><span id="line-3878"> Put put = null;</span>
<span class="source-line-no">3879</span><span id="line-3879"> KeyValue kv13 = new KeyValue(row1, fam1, qf1, ts3, KeyValue.Type.Put, null);</span>
<span class="source-line-no">3880</span><span id="line-3880"> KeyValue kv12 = new KeyValue(row1, fam1, qf1, ts2, KeyValue.Type.Put, null);</span>
<span class="source-line-no">3881</span><span id="line-3881"> KeyValue kv11 = new KeyValue(row1, fam1, qf1, ts1, KeyValue.Type.Put, null);</span>
<span class="source-line-no">3882</span><span id="line-3882"></span>
<span class="source-line-no">3883</span><span id="line-3883"> KeyValue kv23 = new KeyValue(row1, fam1, qf2, ts3, KeyValue.Type.Put, null);</span>
<span class="source-line-no">3884</span><span id="line-3884"> KeyValue kv22 = new KeyValue(row1, fam1, qf2, ts2, KeyValue.Type.Put, null);</span>
<span class="source-line-no">3885</span><span id="line-3885"> KeyValue kv21 = new KeyValue(row1, fam1, qf2, ts1, KeyValue.Type.Put, null);</span>
<span class="source-line-no">3886</span><span id="line-3886"></span>
<span class="source-line-no">3887</span><span id="line-3887"> put = new Put(row1);</span>
<span class="source-line-no">3888</span><span id="line-3888"> put.add(kv13);</span>
<span class="source-line-no">3889</span><span id="line-3889"> put.add(kv12);</span>
<span class="source-line-no">3890</span><span id="line-3890"> put.add(kv11);</span>
<span class="source-line-no">3891</span><span id="line-3891"> put.add(kv23);</span>
<span class="source-line-no">3892</span><span id="line-3892"> put.add(kv22);</span>
<span class="source-line-no">3893</span><span id="line-3893"> put.add(kv21);</span>
<span class="source-line-no">3894</span><span id="line-3894"> region.put(put);</span>
<span class="source-line-no">3895</span><span id="line-3895"> region.flush(true);</span>
<span class="source-line-no">3896</span><span id="line-3896"></span>
<span class="source-line-no">3897</span><span id="line-3897"> // Expected</span>
<span class="source-line-no">3898</span><span id="line-3898"> List&lt;ExtendedCell&gt; expected = new ArrayList&lt;&gt;();</span>
<span class="source-line-no">3899</span><span id="line-3899"> expected.add(kv13);</span>
<span class="source-line-no">3900</span><span id="line-3900"> expected.add(kv12);</span>
<span class="source-line-no">3901</span><span id="line-3901"> expected.add(kv23);</span>
<span class="source-line-no">3902</span><span id="line-3902"> expected.add(kv22);</span>
<span class="source-line-no">3903</span><span id="line-3903"></span>
<span class="source-line-no">3904</span><span id="line-3904"> Scan scan = new Scan().withStartRow(row1);</span>
<span class="source-line-no">3905</span><span id="line-3905"> scan.addColumn(fam1, qf1);</span>
<span class="source-line-no">3906</span><span id="line-3906"> scan.addColumn(fam1, qf2);</span>
<span class="source-line-no">3907</span><span id="line-3907"> scan.readVersions(MAX_VERSIONS);</span>
<span class="source-line-no">3908</span><span id="line-3908"> List&lt;ExtendedCell&gt; actual = new ArrayList&lt;&gt;();</span>
<span class="source-line-no">3909</span><span id="line-3909"> try (InternalScanner scanner = region.getScanner(scan)) {</span>
<span class="source-line-no">3910</span><span id="line-3910"> boolean hasNext = scanner.next((List) actual);</span>
<span class="source-line-no">3911</span><span id="line-3911"> assertEquals(false, hasNext);</span>
<span class="source-line-no">3912</span><span id="line-3912"></span>
<span class="source-line-no">3913</span><span id="line-3913"> // Verify result</span>
<span class="source-line-no">3914</span><span id="line-3914"> for (int i = 0; i &lt; expected.size(); i++) {</span>
<span class="source-line-no">3915</span><span id="line-3915"> assertTrue(PrivateCellUtil.equalsIgnoreMvccVersion(expected.get(i), actual.get(i)));</span>
<span class="source-line-no">3916</span><span id="line-3916"> }</span>
<span class="source-line-no">3917</span><span id="line-3917"> }</span>
<span class="source-line-no">3918</span><span id="line-3918"> }</span>
<span class="source-line-no">3919</span><span id="line-3919"></span>
<span class="source-line-no">3920</span><span id="line-3920"> @Test</span>
<span class="source-line-no">3921</span><span id="line-3921"> public void testScanner_ExplicitColumns_FromMemStoreAndFiles_EnforceVersions()</span>
<span class="source-line-no">3922</span><span id="line-3922"> throws IOException {</span>
<span class="source-line-no">3923</span><span id="line-3923"> byte[] row1 = Bytes.toBytes("row1");</span>
<span class="source-line-no">3924</span><span id="line-3924"> byte[] fam1 = Bytes.toBytes("fam1");</span>
<span class="source-line-no">3925</span><span id="line-3925"> byte[][] families = { fam1 };</span>
<span class="source-line-no">3926</span><span id="line-3926"> byte[] qf1 = Bytes.toBytes("qualifier1");</span>
<span class="source-line-no">3927</span><span id="line-3927"> byte[] qf2 = Bytes.toBytes("qualifier2");</span>
<span class="source-line-no">3928</span><span id="line-3928"></span>
<span class="source-line-no">3929</span><span id="line-3929"> long ts1 = 1;</span>
<span class="source-line-no">3930</span><span id="line-3930"> long ts2 = ts1 + 1;</span>
<span class="source-line-no">3931</span><span id="line-3931"> long ts3 = ts1 + 2;</span>
<span class="source-line-no">3932</span><span id="line-3932"> long ts4 = ts1 + 3;</span>
<span class="source-line-no">3933</span><span id="line-3933"></span>
<span class="source-line-no">3934</span><span id="line-3934"> // Setting up region</span>
<span class="source-line-no">3935</span><span id="line-3935"> this.region = initHRegion(tableName, method, CONF, families);</span>
<span class="source-line-no">3936</span><span id="line-3936"> // Putting data in Region</span>
<span class="source-line-no">3937</span><span id="line-3937"> KeyValue kv14 = new KeyValue(row1, fam1, qf1, ts4, KeyValue.Type.Put, null);</span>
<span class="source-line-no">3938</span><span id="line-3938"> KeyValue kv13 = new KeyValue(row1, fam1, qf1, ts3, KeyValue.Type.Put, null);</span>
<span class="source-line-no">3939</span><span id="line-3939"> KeyValue kv12 = new KeyValue(row1, fam1, qf1, ts2, KeyValue.Type.Put, null);</span>
<span class="source-line-no">3940</span><span id="line-3940"> KeyValue kv11 = new KeyValue(row1, fam1, qf1, ts1, KeyValue.Type.Put, null);</span>
<span class="source-line-no">3941</span><span id="line-3941"></span>
<span class="source-line-no">3942</span><span id="line-3942"> KeyValue kv24 = new KeyValue(row1, fam1, qf2, ts4, KeyValue.Type.Put, null);</span>
<span class="source-line-no">3943</span><span id="line-3943"> KeyValue kv23 = new KeyValue(row1, fam1, qf2, ts3, KeyValue.Type.Put, null);</span>
<span class="source-line-no">3944</span><span id="line-3944"> KeyValue kv22 = new KeyValue(row1, fam1, qf2, ts2, KeyValue.Type.Put, null);</span>
<span class="source-line-no">3945</span><span id="line-3945"> KeyValue kv21 = new KeyValue(row1, fam1, qf2, ts1, KeyValue.Type.Put, null);</span>
<span class="source-line-no">3946</span><span id="line-3946"></span>
<span class="source-line-no">3947</span><span id="line-3947"> Put put = null;</span>
<span class="source-line-no">3948</span><span id="line-3948"> put = new Put(row1);</span>
<span class="source-line-no">3949</span><span id="line-3949"> put.add(kv14);</span>
<span class="source-line-no">3950</span><span id="line-3950"> put.add(kv24);</span>
<span class="source-line-no">3951</span><span id="line-3951"> region.put(put);</span>
<span class="source-line-no">3952</span><span id="line-3952"> region.flush(true);</span>
<span class="source-line-no">3953</span><span id="line-3953"></span>
<span class="source-line-no">3954</span><span id="line-3954"> put = new Put(row1);</span>
<span class="source-line-no">3955</span><span id="line-3955"> put.add(kv23);</span>
<span class="source-line-no">3956</span><span id="line-3956"> put.add(kv13);</span>
<span class="source-line-no">3957</span><span id="line-3957"> region.put(put);</span>
<span class="source-line-no">3958</span><span id="line-3958"> region.flush(true);</span>
<span class="source-line-no">3959</span><span id="line-3959"></span>
<span class="source-line-no">3960</span><span id="line-3960"> put = new Put(row1);</span>
<span class="source-line-no">3961</span><span id="line-3961"> put.add(kv22);</span>
<span class="source-line-no">3962</span><span id="line-3962"> put.add(kv12);</span>
<span class="source-line-no">3963</span><span id="line-3963"> region.put(put);</span>
<span class="source-line-no">3964</span><span id="line-3964"> region.flush(true);</span>
<span class="source-line-no">3965</span><span id="line-3965"></span>
<span class="source-line-no">3966</span><span id="line-3966"> put = new Put(row1);</span>
<span class="source-line-no">3967</span><span id="line-3967"> put.add(kv21);</span>
<span class="source-line-no">3968</span><span id="line-3968"> put.add(kv11);</span>
<span class="source-line-no">3969</span><span id="line-3969"> region.put(put);</span>
<span class="source-line-no">3970</span><span id="line-3970"></span>
<span class="source-line-no">3971</span><span id="line-3971"> // Expected</span>
<span class="source-line-no">3972</span><span id="line-3972"> List&lt;ExtendedCell&gt; expected = new ArrayList&lt;&gt;();</span>
<span class="source-line-no">3973</span><span id="line-3973"> expected.add(kv14);</span>
<span class="source-line-no">3974</span><span id="line-3974"> expected.add(kv13);</span>
<span class="source-line-no">3975</span><span id="line-3975"> expected.add(kv12);</span>
<span class="source-line-no">3976</span><span id="line-3976"> expected.add(kv24);</span>
<span class="source-line-no">3977</span><span id="line-3977"> expected.add(kv23);</span>
<span class="source-line-no">3978</span><span id="line-3978"> expected.add(kv22);</span>
<span class="source-line-no">3979</span><span id="line-3979"></span>
<span class="source-line-no">3980</span><span id="line-3980"> Scan scan = new Scan().withStartRow(row1);</span>
<span class="source-line-no">3981</span><span id="line-3981"> scan.addColumn(fam1, qf1);</span>
<span class="source-line-no">3982</span><span id="line-3982"> scan.addColumn(fam1, qf2);</span>
<span class="source-line-no">3983</span><span id="line-3983"> int versions = 3;</span>
<span class="source-line-no">3984</span><span id="line-3984"> scan.readVersions(versions);</span>
<span class="source-line-no">3985</span><span id="line-3985"> List&lt;ExtendedCell&gt; actual = new ArrayList&lt;&gt;();</span>
<span class="source-line-no">3986</span><span id="line-3986"> try (InternalScanner scanner = region.getScanner(scan)) {</span>
<span class="source-line-no">3987</span><span id="line-3987"> boolean hasNext = scanner.next((List) actual);</span>
<span class="source-line-no">3988</span><span id="line-3988"> assertEquals(false, hasNext);</span>
<span class="source-line-no">3989</span><span id="line-3989"></span>
<span class="source-line-no">3990</span><span id="line-3990"> // Verify result</span>
<span class="source-line-no">3991</span><span id="line-3991"> for (int i = 0; i &lt; expected.size(); i++) {</span>
<span class="source-line-no">3992</span><span id="line-3992"> assertTrue(PrivateCellUtil.equalsIgnoreMvccVersion(expected.get(i), actual.get(i)));</span>
<span class="source-line-no">3993</span><span id="line-3993"> }</span>
<span class="source-line-no">3994</span><span id="line-3994"> }</span>
<span class="source-line-no">3995</span><span id="line-3995"> }</span>
<span class="source-line-no">3996</span><span id="line-3996"></span>
<span class="source-line-no">3997</span><span id="line-3997"> @Test</span>
<span class="source-line-no">3998</span><span id="line-3998"> public void testScanner_Wildcard_FromMemStore_EnforceVersions() throws IOException {</span>
<span class="source-line-no">3999</span><span id="line-3999"> byte[] row1 = Bytes.toBytes("row1");</span>
<span class="source-line-no">4000</span><span id="line-4000"> byte[] qf1 = Bytes.toBytes("qualifier1");</span>
<span class="source-line-no">4001</span><span id="line-4001"> byte[] qf2 = Bytes.toBytes("qualifier2");</span>
<span class="source-line-no">4002</span><span id="line-4002"> byte[] fam1 = Bytes.toBytes("fam1");</span>
<span class="source-line-no">4003</span><span id="line-4003"> byte[][] families = { fam1 };</span>
<span class="source-line-no">4004</span><span id="line-4004"></span>
<span class="source-line-no">4005</span><span id="line-4005"> long ts1 = EnvironmentEdgeManager.currentTime();</span>
<span class="source-line-no">4006</span><span id="line-4006"> long ts2 = ts1 + 1;</span>
<span class="source-line-no">4007</span><span id="line-4007"> long ts3 = ts1 + 2;</span>
<span class="source-line-no">4008</span><span id="line-4008"></span>
<span class="source-line-no">4009</span><span id="line-4009"> // Setting up region</span>
<span class="source-line-no">4010</span><span id="line-4010"> this.region = initHRegion(tableName, method, CONF, families);</span>
<span class="source-line-no">4011</span><span id="line-4011"> // Putting data in Region</span>
<span class="source-line-no">4012</span><span id="line-4012"> Put put = null;</span>
<span class="source-line-no">4013</span><span id="line-4013"> KeyValue kv13 = new KeyValue(row1, fam1, qf1, ts3, KeyValue.Type.Put, null);</span>
<span class="source-line-no">4014</span><span id="line-4014"> KeyValue kv12 = new KeyValue(row1, fam1, qf1, ts2, KeyValue.Type.Put, null);</span>
<span class="source-line-no">4015</span><span id="line-4015"> KeyValue kv11 = new KeyValue(row1, fam1, qf1, ts1, KeyValue.Type.Put, null);</span>
<span class="source-line-no">4016</span><span id="line-4016"></span>
<span class="source-line-no">4017</span><span id="line-4017"> KeyValue kv23 = new KeyValue(row1, fam1, qf2, ts3, KeyValue.Type.Put, null);</span>
<span class="source-line-no">4018</span><span id="line-4018"> KeyValue kv22 = new KeyValue(row1, fam1, qf2, ts2, KeyValue.Type.Put, null);</span>
<span class="source-line-no">4019</span><span id="line-4019"> KeyValue kv21 = new KeyValue(row1, fam1, qf2, ts1, KeyValue.Type.Put, null);</span>
<span class="source-line-no">4020</span><span id="line-4020"></span>
<span class="source-line-no">4021</span><span id="line-4021"> put = new Put(row1);</span>
<span class="source-line-no">4022</span><span id="line-4022"> put.add(kv13);</span>
<span class="source-line-no">4023</span><span id="line-4023"> put.add(kv12);</span>
<span class="source-line-no">4024</span><span id="line-4024"> put.add(kv11);</span>
<span class="source-line-no">4025</span><span id="line-4025"> put.add(kv23);</span>
<span class="source-line-no">4026</span><span id="line-4026"> put.add(kv22);</span>
<span class="source-line-no">4027</span><span id="line-4027"> put.add(kv21);</span>
<span class="source-line-no">4028</span><span id="line-4028"> region.put(put);</span>
<span class="source-line-no">4029</span><span id="line-4029"></span>
<span class="source-line-no">4030</span><span id="line-4030"> // Expected</span>
<span class="source-line-no">4031</span><span id="line-4031"> List&lt;Cell&gt; expected = new ArrayList&lt;&gt;();</span>
<span class="source-line-no">4032</span><span id="line-4032"> expected.add(kv13);</span>
<span class="source-line-no">4033</span><span id="line-4033"> expected.add(kv12);</span>
<span class="source-line-no">4034</span><span id="line-4034"> expected.add(kv23);</span>
<span class="source-line-no">4035</span><span id="line-4035"> expected.add(kv22);</span>
<span class="source-line-no">4036</span><span id="line-4036"></span>
<span class="source-line-no">4037</span><span id="line-4037"> Scan scan = new Scan().withStartRow(row1);</span>
<span class="source-line-no">4038</span><span id="line-4038"> scan.addFamily(fam1);</span>
<span class="source-line-no">4039</span><span id="line-4039"> scan.readVersions(MAX_VERSIONS);</span>
<span class="source-line-no">4040</span><span id="line-4040"> List&lt;Cell&gt; actual = new ArrayList&lt;&gt;();</span>
<span class="source-line-no">4041</span><span id="line-4041"> try (InternalScanner scanner = region.getScanner(scan)) {</span>
<span class="source-line-no">4042</span><span id="line-4042"> boolean hasNext = scanner.next(actual);</span>
<span class="source-line-no">4043</span><span id="line-4043"> assertEquals(false, hasNext);</span>
<span class="source-line-no">4044</span><span id="line-4044"></span>
<span class="source-line-no">4045</span><span id="line-4045"> // Verify result</span>
<span class="source-line-no">4046</span><span id="line-4046"> for (int i = 0; i &lt; expected.size(); i++) {</span>
<span class="source-line-no">4047</span><span id="line-4047"> assertEquals(expected.get(i), actual.get(i));</span>
<span class="source-line-no">4048</span><span id="line-4048"> }</span>
<span class="source-line-no">4049</span><span id="line-4049"> }</span>
<span class="source-line-no">4050</span><span id="line-4050"> }</span>
<span class="source-line-no">4051</span><span id="line-4051"></span>
<span class="source-line-no">4052</span><span id="line-4052"> @Test</span>
<span class="source-line-no">4053</span><span id="line-4053"> public void testScanner_Wildcard_FromFilesOnly_EnforceVersions() throws IOException {</span>
<span class="source-line-no">4054</span><span id="line-4054"> byte[] row1 = Bytes.toBytes("row1");</span>
<span class="source-line-no">4055</span><span id="line-4055"> byte[] qf1 = Bytes.toBytes("qualifier1");</span>
<span class="source-line-no">4056</span><span id="line-4056"> byte[] qf2 = Bytes.toBytes("qualifier2");</span>
<span class="source-line-no">4057</span><span id="line-4057"> byte[] fam1 = Bytes.toBytes("fam1");</span>
<span class="source-line-no">4058</span><span id="line-4058"></span>
<span class="source-line-no">4059</span><span id="line-4059"> long ts1 = 1;</span>
<span class="source-line-no">4060</span><span id="line-4060"> long ts2 = ts1 + 1;</span>
<span class="source-line-no">4061</span><span id="line-4061"> long ts3 = ts1 + 2;</span>
<span class="source-line-no">4062</span><span id="line-4062"></span>
<span class="source-line-no">4063</span><span id="line-4063"> // Setting up region</span>
<span class="source-line-no">4064</span><span id="line-4064"> this.region = initHRegion(tableName, method, CONF, fam1);</span>
<span class="source-line-no">4065</span><span id="line-4065"> // Putting data in Region</span>
<span class="source-line-no">4066</span><span id="line-4066"> Put put = null;</span>
<span class="source-line-no">4067</span><span id="line-4067"> KeyValue kv13 = new KeyValue(row1, fam1, qf1, ts3, KeyValue.Type.Put, null);</span>
<span class="source-line-no">4068</span><span id="line-4068"> KeyValue kv12 = new KeyValue(row1, fam1, qf1, ts2, KeyValue.Type.Put, null);</span>
<span class="source-line-no">4069</span><span id="line-4069"> KeyValue kv11 = new KeyValue(row1, fam1, qf1, ts1, KeyValue.Type.Put, null);</span>
<span class="source-line-no">4070</span><span id="line-4070"></span>
<span class="source-line-no">4071</span><span id="line-4071"> KeyValue kv23 = new KeyValue(row1, fam1, qf2, ts3, KeyValue.Type.Put, null);</span>
<span class="source-line-no">4072</span><span id="line-4072"> KeyValue kv22 = new KeyValue(row1, fam1, qf2, ts2, KeyValue.Type.Put, null);</span>
<span class="source-line-no">4073</span><span id="line-4073"> KeyValue kv21 = new KeyValue(row1, fam1, qf2, ts1, KeyValue.Type.Put, null);</span>
<span class="source-line-no">4074</span><span id="line-4074"></span>
<span class="source-line-no">4075</span><span id="line-4075"> put = new Put(row1);</span>
<span class="source-line-no">4076</span><span id="line-4076"> put.add(kv13);</span>
<span class="source-line-no">4077</span><span id="line-4077"> put.add(kv12);</span>
<span class="source-line-no">4078</span><span id="line-4078"> put.add(kv11);</span>
<span class="source-line-no">4079</span><span id="line-4079"> put.add(kv23);</span>
<span class="source-line-no">4080</span><span id="line-4080"> put.add(kv22);</span>
<span class="source-line-no">4081</span><span id="line-4081"> put.add(kv21);</span>
<span class="source-line-no">4082</span><span id="line-4082"> region.put(put);</span>
<span class="source-line-no">4083</span><span id="line-4083"> region.flush(true);</span>
<span class="source-line-no">4084</span><span id="line-4084"></span>
<span class="source-line-no">4085</span><span id="line-4085"> // Expected</span>
<span class="source-line-no">4086</span><span id="line-4086"> List&lt;ExtendedCell&gt; expected = new ArrayList&lt;&gt;();</span>
<span class="source-line-no">4087</span><span id="line-4087"> expected.add(kv13);</span>
<span class="source-line-no">4088</span><span id="line-4088"> expected.add(kv12);</span>
<span class="source-line-no">4089</span><span id="line-4089"> expected.add(kv23);</span>
<span class="source-line-no">4090</span><span id="line-4090"> expected.add(kv22);</span>
<span class="source-line-no">4091</span><span id="line-4091"></span>
<span class="source-line-no">4092</span><span id="line-4092"> Scan scan = new Scan().withStartRow(row1);</span>
<span class="source-line-no">4093</span><span id="line-4093"> scan.addFamily(fam1);</span>
<span class="source-line-no">4094</span><span id="line-4094"> scan.readVersions(MAX_VERSIONS);</span>
<span class="source-line-no">4095</span><span id="line-4095"> List&lt;ExtendedCell&gt; actual = new ArrayList&lt;&gt;();</span>
<span class="source-line-no">4096</span><span id="line-4096"> try (InternalScanner scanner = region.getScanner(scan)) {</span>
<span class="source-line-no">4097</span><span id="line-4097"> boolean hasNext = scanner.next((List) actual);</span>
<span class="source-line-no">4098</span><span id="line-4098"> assertEquals(false, hasNext);</span>
<span class="source-line-no">4099</span><span id="line-4099"></span>
<span class="source-line-no">4100</span><span id="line-4100"> // Verify result</span>
<span class="source-line-no">4101</span><span id="line-4101"> for (int i = 0; i &lt; expected.size(); i++) {</span>
<span class="source-line-no">4102</span><span id="line-4102"> assertTrue(PrivateCellUtil.equalsIgnoreMvccVersion(expected.get(i), actual.get(i)));</span>
<span class="source-line-no">4103</span><span id="line-4103"> }</span>
<span class="source-line-no">4104</span><span id="line-4104"> }</span>
<span class="source-line-no">4105</span><span id="line-4105"> }</span>
<span class="source-line-no">4106</span><span id="line-4106"></span>
<span class="source-line-no">4107</span><span id="line-4107"> @Test</span>
<span class="source-line-no">4108</span><span id="line-4108"> public void testScanner_StopRow1542() throws IOException {</span>
<span class="source-line-no">4109</span><span id="line-4109"> byte[] family = Bytes.toBytes("testFamily");</span>
<span class="source-line-no">4110</span><span id="line-4110"> this.region = initHRegion(tableName, method, CONF, family);</span>
<span class="source-line-no">4111</span><span id="line-4111"> byte[] row1 = Bytes.toBytes("row111");</span>
<span class="source-line-no">4112</span><span id="line-4112"> byte[] row2 = Bytes.toBytes("row222");</span>
<span class="source-line-no">4113</span><span id="line-4113"> byte[] row3 = Bytes.toBytes("row333");</span>
<span class="source-line-no">4114</span><span id="line-4114"> byte[] row4 = Bytes.toBytes("row444");</span>
<span class="source-line-no">4115</span><span id="line-4115"> byte[] row5 = Bytes.toBytes("row555");</span>
<span class="source-line-no">4116</span><span id="line-4116"></span>
<span class="source-line-no">4117</span><span id="line-4117"> byte[] col1 = Bytes.toBytes("Pub111");</span>
<span class="source-line-no">4118</span><span id="line-4118"> byte[] col2 = Bytes.toBytes("Pub222");</span>
<span class="source-line-no">4119</span><span id="line-4119"></span>
<span class="source-line-no">4120</span><span id="line-4120"> Put put = new Put(row1);</span>
<span class="source-line-no">4121</span><span id="line-4121"> put.addColumn(family, col1, Bytes.toBytes(10L));</span>
<span class="source-line-no">4122</span><span id="line-4122"> region.put(put);</span>
<span class="source-line-no">4123</span><span id="line-4123"></span>
<span class="source-line-no">4124</span><span id="line-4124"> put = new Put(row2);</span>
<span class="source-line-no">4125</span><span id="line-4125"> put.addColumn(family, col1, Bytes.toBytes(15L));</span>
<span class="source-line-no">4126</span><span id="line-4126"> region.put(put);</span>
<span class="source-line-no">4127</span><span id="line-4127"></span>
<span class="source-line-no">4128</span><span id="line-4128"> put = new Put(row3);</span>
<span class="source-line-no">4129</span><span id="line-4129"> put.addColumn(family, col2, Bytes.toBytes(20L));</span>
<span class="source-line-no">4130</span><span id="line-4130"> region.put(put);</span>
<span class="source-line-no">4131</span><span id="line-4131"></span>
<span class="source-line-no">4132</span><span id="line-4132"> put = new Put(row4);</span>
<span class="source-line-no">4133</span><span id="line-4133"> put.addColumn(family, col2, Bytes.toBytes(30L));</span>
<span class="source-line-no">4134</span><span id="line-4134"> region.put(put);</span>
<span class="source-line-no">4135</span><span id="line-4135"></span>
<span class="source-line-no">4136</span><span id="line-4136"> put = new Put(row5);</span>
<span class="source-line-no">4137</span><span id="line-4137"> put.addColumn(family, col1, Bytes.toBytes(40L));</span>
<span class="source-line-no">4138</span><span id="line-4138"> region.put(put);</span>
<span class="source-line-no">4139</span><span id="line-4139"></span>
<span class="source-line-no">4140</span><span id="line-4140"> Scan scan = new Scan().withStartRow(row3).withStopRow(row4);</span>
<span class="source-line-no">4141</span><span id="line-4141"> scan.readAllVersions();</span>
<span class="source-line-no">4142</span><span id="line-4142"> scan.addColumn(family, col1);</span>
<span class="source-line-no">4143</span><span id="line-4143"> try (InternalScanner s = region.getScanner(scan)) {</span>
<span class="source-line-no">4144</span><span id="line-4144"> List&lt;Cell&gt; results = new ArrayList&lt;&gt;();</span>
<span class="source-line-no">4145</span><span id="line-4145"> assertEquals(false, s.next(results));</span>
<span class="source-line-no">4146</span><span id="line-4146"> assertEquals(0, results.size());</span>
<span class="source-line-no">4147</span><span id="line-4147"> }</span>
<span class="source-line-no">4148</span><span id="line-4148"> }</span>
<span class="source-line-no">4149</span><span id="line-4149"></span>
<span class="source-line-no">4150</span><span id="line-4150"> @Test</span>
<span class="source-line-no">4151</span><span id="line-4151"> public void testScanner_Wildcard_FromMemStoreAndFiles_EnforceVersions() throws IOException {</span>
<span class="source-line-no">4152</span><span id="line-4152"> byte[] row1 = Bytes.toBytes("row1");</span>
<span class="source-line-no">4153</span><span id="line-4153"> byte[] fam1 = Bytes.toBytes("fam1");</span>
<span class="source-line-no">4154</span><span id="line-4154"> byte[] qf1 = Bytes.toBytes("qualifier1");</span>
<span class="source-line-no">4155</span><span id="line-4155"> byte[] qf2 = Bytes.toBytes("quateslifier2");</span>
<span class="source-line-no">4156</span><span id="line-4156"></span>
<span class="source-line-no">4157</span><span id="line-4157"> long ts1 = 1;</span>
<span class="source-line-no">4158</span><span id="line-4158"> long ts2 = ts1 + 1;</span>
<span class="source-line-no">4159</span><span id="line-4159"> long ts3 = ts1 + 2;</span>
<span class="source-line-no">4160</span><span id="line-4160"> long ts4 = ts1 + 3;</span>
<span class="source-line-no">4161</span><span id="line-4161"></span>
<span class="source-line-no">4162</span><span id="line-4162"> // Setting up region</span>
<span class="source-line-no">4163</span><span id="line-4163"> this.region = initHRegion(tableName, method, CONF, fam1);</span>
<span class="source-line-no">4164</span><span id="line-4164"> // Putting data in Region</span>
<span class="source-line-no">4165</span><span id="line-4165"> KeyValue kv14 = new KeyValue(row1, fam1, qf1, ts4, KeyValue.Type.Put, null);</span>
<span class="source-line-no">4166</span><span id="line-4166"> KeyValue kv13 = new KeyValue(row1, fam1, qf1, ts3, KeyValue.Type.Put, null);</span>
<span class="source-line-no">4167</span><span id="line-4167"> KeyValue kv12 = new KeyValue(row1, fam1, qf1, ts2, KeyValue.Type.Put, null);</span>
<span class="source-line-no">4168</span><span id="line-4168"> KeyValue kv11 = new KeyValue(row1, fam1, qf1, ts1, KeyValue.Type.Put, null);</span>
<span class="source-line-no">4169</span><span id="line-4169"></span>
<span class="source-line-no">4170</span><span id="line-4170"> KeyValue kv24 = new KeyValue(row1, fam1, qf2, ts4, KeyValue.Type.Put, null);</span>
<span class="source-line-no">4171</span><span id="line-4171"> KeyValue kv23 = new KeyValue(row1, fam1, qf2, ts3, KeyValue.Type.Put, null);</span>
<span class="source-line-no">4172</span><span id="line-4172"> KeyValue kv22 = new KeyValue(row1, fam1, qf2, ts2, KeyValue.Type.Put, null);</span>
<span class="source-line-no">4173</span><span id="line-4173"> KeyValue kv21 = new KeyValue(row1, fam1, qf2, ts1, KeyValue.Type.Put, null);</span>
<span class="source-line-no">4174</span><span id="line-4174"></span>
<span class="source-line-no">4175</span><span id="line-4175"> Put put = null;</span>
<span class="source-line-no">4176</span><span id="line-4176"> put = new Put(row1);</span>
<span class="source-line-no">4177</span><span id="line-4177"> put.add(kv14);</span>
<span class="source-line-no">4178</span><span id="line-4178"> put.add(kv24);</span>
<span class="source-line-no">4179</span><span id="line-4179"> region.put(put);</span>
<span class="source-line-no">4180</span><span id="line-4180"> region.flush(true);</span>
<span class="source-line-no">4181</span><span id="line-4181"></span>
<span class="source-line-no">4182</span><span id="line-4182"> put = new Put(row1);</span>
<span class="source-line-no">4183</span><span id="line-4183"> put.add(kv23);</span>
<span class="source-line-no">4184</span><span id="line-4184"> put.add(kv13);</span>
<span class="source-line-no">4185</span><span id="line-4185"> region.put(put);</span>
<span class="source-line-no">4186</span><span id="line-4186"> region.flush(true);</span>
<span class="source-line-no">4187</span><span id="line-4187"></span>
<span class="source-line-no">4188</span><span id="line-4188"> put = new Put(row1);</span>
<span class="source-line-no">4189</span><span id="line-4189"> put.add(kv22);</span>
<span class="source-line-no">4190</span><span id="line-4190"> put.add(kv12);</span>
<span class="source-line-no">4191</span><span id="line-4191"> region.put(put);</span>
<span class="source-line-no">4192</span><span id="line-4192"> region.flush(true);</span>
<span class="source-line-no">4193</span><span id="line-4193"></span>
<span class="source-line-no">4194</span><span id="line-4194"> put = new Put(row1);</span>
<span class="source-line-no">4195</span><span id="line-4195"> put.add(kv21);</span>
<span class="source-line-no">4196</span><span id="line-4196"> put.add(kv11);</span>
<span class="source-line-no">4197</span><span id="line-4197"> region.put(put);</span>
<span class="source-line-no">4198</span><span id="line-4198"></span>
<span class="source-line-no">4199</span><span id="line-4199"> // Expected</span>
<span class="source-line-no">4200</span><span id="line-4200"> List&lt;KeyValue&gt; expected = new ArrayList&lt;&gt;();</span>
<span class="source-line-no">4201</span><span id="line-4201"> expected.add(kv14);</span>
<span class="source-line-no">4202</span><span id="line-4202"> expected.add(kv13);</span>
<span class="source-line-no">4203</span><span id="line-4203"> expected.add(kv12);</span>
<span class="source-line-no">4204</span><span id="line-4204"> expected.add(kv24);</span>
<span class="source-line-no">4205</span><span id="line-4205"> expected.add(kv23);</span>
<span class="source-line-no">4206</span><span id="line-4206"> expected.add(kv22);</span>
<span class="source-line-no">4207</span><span id="line-4207"></span>
<span class="source-line-no">4208</span><span id="line-4208"> Scan scan = new Scan().withStartRow(row1);</span>
<span class="source-line-no">4209</span><span id="line-4209"> int versions = 3;</span>
<span class="source-line-no">4210</span><span id="line-4210"> scan.readVersions(versions);</span>
<span class="source-line-no">4211</span><span id="line-4211"> List&lt;ExtendedCell&gt; actual = new ArrayList&lt;&gt;();</span>
<span class="source-line-no">4212</span><span id="line-4212"> try (InternalScanner scanner = region.getScanner(scan)) {</span>
<span class="source-line-no">4213</span><span id="line-4213"> boolean hasNext = scanner.next((List) actual);</span>
<span class="source-line-no">4214</span><span id="line-4214"> assertEquals(false, hasNext);</span>
<span class="source-line-no">4215</span><span id="line-4215"></span>
<span class="source-line-no">4216</span><span id="line-4216"> // Verify result</span>
<span class="source-line-no">4217</span><span id="line-4217"> for (int i = 0; i &lt; expected.size(); i++) {</span>
<span class="source-line-no">4218</span><span id="line-4218"> assertTrue(PrivateCellUtil.equalsIgnoreMvccVersion(expected.get(i), actual.get(i)));</span>
<span class="source-line-no">4219</span><span id="line-4219"> }</span>
<span class="source-line-no">4220</span><span id="line-4220"> }</span>
<span class="source-line-no">4221</span><span id="line-4221"> }</span>
<span class="source-line-no">4222</span><span id="line-4222"></span>
<span class="source-line-no">4223</span><span id="line-4223"> /**</span>
<span class="source-line-no">4224</span><span id="line-4224"> * Added for HBASE-5416 Here we test scan optimization when only subset of CFs are used in filter</span>
<span class="source-line-no">4225</span><span id="line-4225"> * conditions.</span>
<span class="source-line-no">4226</span><span id="line-4226"> */</span>
<span class="source-line-no">4227</span><span id="line-4227"> @Test</span>
<span class="source-line-no">4228</span><span id="line-4228"> public void testScanner_JoinedScanners() throws IOException {</span>
<span class="source-line-no">4229</span><span id="line-4229"> byte[] cf_essential = Bytes.toBytes("essential");</span>
<span class="source-line-no">4230</span><span id="line-4230"> byte[] cf_joined = Bytes.toBytes("joined");</span>
<span class="source-line-no">4231</span><span id="line-4231"> byte[] cf_alpha = Bytes.toBytes("alpha");</span>
<span class="source-line-no">4232</span><span id="line-4232"> this.region = initHRegion(tableName, method, CONF, cf_essential, cf_joined, cf_alpha);</span>
<span class="source-line-no">4233</span><span id="line-4233"> byte[] row1 = Bytes.toBytes("row1");</span>
<span class="source-line-no">4234</span><span id="line-4234"> byte[] row2 = Bytes.toBytes("row2");</span>
<span class="source-line-no">4235</span><span id="line-4235"> byte[] row3 = Bytes.toBytes("row3");</span>
<span class="source-line-no">4236</span><span id="line-4236"></span>
<span class="source-line-no">4237</span><span id="line-4237"> byte[] col_normal = Bytes.toBytes("d");</span>
<span class="source-line-no">4238</span><span id="line-4238"> byte[] col_alpha = Bytes.toBytes("a");</span>
<span class="source-line-no">4239</span><span id="line-4239"></span>
<span class="source-line-no">4240</span><span id="line-4240"> byte[] filtered_val = Bytes.toBytes(3);</span>
<span class="source-line-no">4241</span><span id="line-4241"></span>
<span class="source-line-no">4242</span><span id="line-4242"> Put put = new Put(row1);</span>
<span class="source-line-no">4243</span><span id="line-4243"> put.addColumn(cf_essential, col_normal, Bytes.toBytes(1));</span>
<span class="source-line-no">4244</span><span id="line-4244"> put.addColumn(cf_joined, col_alpha, Bytes.toBytes(1));</span>
<span class="source-line-no">4245</span><span id="line-4245"> region.put(put);</span>
<span class="source-line-no">4246</span><span id="line-4246"></span>
<span class="source-line-no">4247</span><span id="line-4247"> put = new Put(row2);</span>
<span class="source-line-no">4248</span><span id="line-4248"> put.addColumn(cf_essential, col_alpha, Bytes.toBytes(2));</span>
<span class="source-line-no">4249</span><span id="line-4249"> put.addColumn(cf_joined, col_normal, Bytes.toBytes(2));</span>
<span class="source-line-no">4250</span><span id="line-4250"> put.addColumn(cf_alpha, col_alpha, Bytes.toBytes(2));</span>
<span class="source-line-no">4251</span><span id="line-4251"> region.put(put);</span>
<span class="source-line-no">4252</span><span id="line-4252"></span>
<span class="source-line-no">4253</span><span id="line-4253"> put = new Put(row3);</span>
<span class="source-line-no">4254</span><span id="line-4254"> put.addColumn(cf_essential, col_normal, filtered_val);</span>
<span class="source-line-no">4255</span><span id="line-4255"> put.addColumn(cf_joined, col_normal, filtered_val);</span>
<span class="source-line-no">4256</span><span id="line-4256"> region.put(put);</span>
<span class="source-line-no">4257</span><span id="line-4257"></span>
<span class="source-line-no">4258</span><span id="line-4258"> // Check two things:</span>
<span class="source-line-no">4259</span><span id="line-4259"> // 1. result list contains expected values</span>
<span class="source-line-no">4260</span><span id="line-4260"> // 2. result list is sorted properly</span>
<span class="source-line-no">4261</span><span id="line-4261"></span>
<span class="source-line-no">4262</span><span id="line-4262"> Scan scan = new Scan();</span>
<span class="source-line-no">4263</span><span id="line-4263"> Filter filter = new SingleColumnValueExcludeFilter(cf_essential, col_normal,</span>
<span class="source-line-no">4264</span><span id="line-4264"> CompareOperator.NOT_EQUAL, filtered_val);</span>
<span class="source-line-no">4265</span><span id="line-4265"> scan.setFilter(filter);</span>
<span class="source-line-no">4266</span><span id="line-4266"> scan.setLoadColumnFamiliesOnDemand(true);</span>
<span class="source-line-no">4267</span><span id="line-4267"> try (InternalScanner s = region.getScanner(scan)) {</span>
<span class="source-line-no">4268</span><span id="line-4268"> List&lt;Cell&gt; results = new ArrayList&lt;&gt;();</span>
<span class="source-line-no">4269</span><span id="line-4269"> assertTrue(s.next(results));</span>
<span class="source-line-no">4270</span><span id="line-4270"> assertEquals(1, results.size());</span>
<span class="source-line-no">4271</span><span id="line-4271"> results.clear();</span>
<span class="source-line-no">4272</span><span id="line-4272"></span>
<span class="source-line-no">4273</span><span id="line-4273"> assertTrue(s.next(results));</span>
<span class="source-line-no">4274</span><span id="line-4274"> assertEquals(3, results.size());</span>
<span class="source-line-no">4275</span><span id="line-4275"> assertTrue("orderCheck", CellUtil.matchingFamily(results.get(0), cf_alpha));</span>
<span class="source-line-no">4276</span><span id="line-4276"> assertTrue("orderCheck", CellUtil.matchingFamily(results.get(1), cf_essential));</span>
<span class="source-line-no">4277</span><span id="line-4277"> assertTrue("orderCheck", CellUtil.matchingFamily(results.get(2), cf_joined));</span>
<span class="source-line-no">4278</span><span id="line-4278"> results.clear();</span>
<span class="source-line-no">4279</span><span id="line-4279"></span>
<span class="source-line-no">4280</span><span id="line-4280"> assertFalse(s.next(results));</span>
<span class="source-line-no">4281</span><span id="line-4281"> assertEquals(0, results.size());</span>
<span class="source-line-no">4282</span><span id="line-4282"> }</span>
<span class="source-line-no">4283</span><span id="line-4283"> }</span>
<span class="source-line-no">4284</span><span id="line-4284"></span>
<span class="source-line-no">4285</span><span id="line-4285"> /**</span>
<span class="source-line-no">4286</span><span id="line-4286"> * HBASE-5416 Test case when scan limits amount of KVs returned on each next() call.</span>
<span class="source-line-no">4287</span><span id="line-4287"> */</span>
<span class="source-line-no">4288</span><span id="line-4288"> @Test</span>
<span class="source-line-no">4289</span><span id="line-4289"> public void testScanner_JoinedScannersWithLimits() throws IOException {</span>
<span class="source-line-no">4290</span><span id="line-4290"> final byte[] cf_first = Bytes.toBytes("first");</span>
<span class="source-line-no">4291</span><span id="line-4291"> final byte[] cf_second = Bytes.toBytes("second");</span>
<span class="source-line-no">4292</span><span id="line-4292"></span>
<span class="source-line-no">4293</span><span id="line-4293"> this.region = initHRegion(tableName, method, CONF, cf_first, cf_second);</span>
<span class="source-line-no">4294</span><span id="line-4294"> final byte[] col_a = Bytes.toBytes("a");</span>
<span class="source-line-no">4295</span><span id="line-4295"> final byte[] col_b = Bytes.toBytes("b");</span>
<span class="source-line-no">4296</span><span id="line-4296"></span>
<span class="source-line-no">4297</span><span id="line-4297"> Put put;</span>
<span class="source-line-no">4298</span><span id="line-4298"></span>
<span class="source-line-no">4299</span><span id="line-4299"> for (int i = 0; i &lt; 10; i++) {</span>
<span class="source-line-no">4300</span><span id="line-4300"> put = new Put(Bytes.toBytes("r" + Integer.toString(i)));</span>
<span class="source-line-no">4301</span><span id="line-4301"> put.addColumn(cf_first, col_a, Bytes.toBytes(i));</span>
<span class="source-line-no">4302</span><span id="line-4302"> if (i &lt; 5) {</span>
<span class="source-line-no">4303</span><span id="line-4303"> put.addColumn(cf_first, col_b, Bytes.toBytes(i));</span>
<span class="source-line-no">4304</span><span id="line-4304"> put.addColumn(cf_second, col_a, Bytes.toBytes(i));</span>
<span class="source-line-no">4305</span><span id="line-4305"> put.addColumn(cf_second, col_b, Bytes.toBytes(i));</span>
<span class="source-line-no">4306</span><span id="line-4306"> }</span>
<span class="source-line-no">4307</span><span id="line-4307"> region.put(put);</span>
<span class="source-line-no">4308</span><span id="line-4308"> }</span>
<span class="source-line-no">4309</span><span id="line-4309"></span>
<span class="source-line-no">4310</span><span id="line-4310"> Scan scan = new Scan();</span>
<span class="source-line-no">4311</span><span id="line-4311"> scan.setLoadColumnFamiliesOnDemand(true);</span>
<span class="source-line-no">4312</span><span id="line-4312"> Filter bogusFilter = new FilterBase() {</span>
<span class="source-line-no">4313</span><span id="line-4313"> @Override</span>
<span class="source-line-no">4314</span><span id="line-4314"> public ReturnCode filterCell(final Cell ignored) throws IOException {</span>
<span class="source-line-no">4315</span><span id="line-4315"> return ReturnCode.INCLUDE;</span>
<span class="source-line-no">4316</span><span id="line-4316"> }</span>
<span class="source-line-no">4317</span><span id="line-4317"></span>
<span class="source-line-no">4318</span><span id="line-4318"> @Override</span>
<span class="source-line-no">4319</span><span id="line-4319"> public boolean isFamilyEssential(byte[] name) {</span>
<span class="source-line-no">4320</span><span id="line-4320"> return Bytes.equals(name, cf_first);</span>
<span class="source-line-no">4321</span><span id="line-4321"> }</span>
<span class="source-line-no">4322</span><span id="line-4322"> };</span>
<span class="source-line-no">4323</span><span id="line-4323"></span>
<span class="source-line-no">4324</span><span id="line-4324"> scan.setFilter(bogusFilter);</span>
<span class="source-line-no">4325</span><span id="line-4325"> try (InternalScanner s = region.getScanner(scan)) {</span>
<span class="source-line-no">4326</span><span id="line-4326"> // Our data looks like this:</span>
<span class="source-line-no">4327</span><span id="line-4327"> // r0: first:a, first:b, second:a, second:b</span>
<span class="source-line-no">4328</span><span id="line-4328"> // r1: first:a, first:b, second:a, second:b</span>
<span class="source-line-no">4329</span><span id="line-4329"> // r2: first:a, first:b, second:a, second:b</span>
<span class="source-line-no">4330</span><span id="line-4330"> // r3: first:a, first:b, second:a, second:b</span>
<span class="source-line-no">4331</span><span id="line-4331"> // r4: first:a, first:b, second:a, second:b</span>
<span class="source-line-no">4332</span><span id="line-4332"> // r5: first:a</span>
<span class="source-line-no">4333</span><span id="line-4333"> // r6: first:a</span>
<span class="source-line-no">4334</span><span id="line-4334"> // r7: first:a</span>
<span class="source-line-no">4335</span><span id="line-4335"> // r8: first:a</span>
<span class="source-line-no">4336</span><span id="line-4336"> // r9: first:a</span>
<span class="source-line-no">4337</span><span id="line-4337"></span>
<span class="source-line-no">4338</span><span id="line-4338"> // But due to next's limit set to 3, we should get this:</span>
<span class="source-line-no">4339</span><span id="line-4339"> // r0: first:a, first:b, second:a</span>
<span class="source-line-no">4340</span><span id="line-4340"> // r0: second:b</span>
<span class="source-line-no">4341</span><span id="line-4341"> // r1: first:a, first:b, second:a</span>
<span class="source-line-no">4342</span><span id="line-4342"> // r1: second:b</span>
<span class="source-line-no">4343</span><span id="line-4343"> // r2: first:a, first:b, second:a</span>
<span class="source-line-no">4344</span><span id="line-4344"> // r2: second:b</span>
<span class="source-line-no">4345</span><span id="line-4345"> // r3: first:a, first:b, second:a</span>
<span class="source-line-no">4346</span><span id="line-4346"> // r3: second:b</span>
<span class="source-line-no">4347</span><span id="line-4347"> // r4: first:a, first:b, second:a</span>
<span class="source-line-no">4348</span><span id="line-4348"> // r4: second:b</span>
<span class="source-line-no">4349</span><span id="line-4349"> // r5: first:a</span>
<span class="source-line-no">4350</span><span id="line-4350"> // r6: first:a</span>
<span class="source-line-no">4351</span><span id="line-4351"> // r7: first:a</span>
<span class="source-line-no">4352</span><span id="line-4352"> // r8: first:a</span>
<span class="source-line-no">4353</span><span id="line-4353"> // r9: first:a</span>
<span class="source-line-no">4354</span><span id="line-4354"></span>
<span class="source-line-no">4355</span><span id="line-4355"> List&lt;Cell&gt; results = new ArrayList&lt;&gt;();</span>
<span class="source-line-no">4356</span><span id="line-4356"> int index = 0;</span>
<span class="source-line-no">4357</span><span id="line-4357"> ScannerContext scannerContext = ScannerContext.newBuilder().setBatchLimit(3).build();</span>
<span class="source-line-no">4358</span><span id="line-4358"> while (true) {</span>
<span class="source-line-no">4359</span><span id="line-4359"> boolean more = s.next(results, scannerContext);</span>
<span class="source-line-no">4360</span><span id="line-4360"> if ((index &gt;&gt; 1) &lt; 5) {</span>
<span class="source-line-no">4361</span><span id="line-4361"> if (index % 2 == 0) {</span>
<span class="source-line-no">4362</span><span id="line-4362"> assertEquals(3, results.size());</span>
<span class="source-line-no">4363</span><span id="line-4363"> } else {</span>
<span class="source-line-no">4364</span><span id="line-4364"> assertEquals(1, results.size());</span>
<span class="source-line-no">4365</span><span id="line-4365"> }</span>
<span class="source-line-no">4366</span><span id="line-4366"> } else {</span>
<span class="source-line-no">4367</span><span id="line-4367"> assertEquals(1, results.size());</span>
<span class="source-line-no">4368</span><span id="line-4368"> }</span>
<span class="source-line-no">4369</span><span id="line-4369"> results.clear();</span>
<span class="source-line-no">4370</span><span id="line-4370"> index++;</span>
<span class="source-line-no">4371</span><span id="line-4371"> if (!more) {</span>
<span class="source-line-no">4372</span><span id="line-4372"> break;</span>
<span class="source-line-no">4373</span><span id="line-4373"> }</span>
<span class="source-line-no">4374</span><span id="line-4374"> }</span>
<span class="source-line-no">4375</span><span id="line-4375"> }</span>
<span class="source-line-no">4376</span><span id="line-4376"> }</span>
<span class="source-line-no">4377</span><span id="line-4377"></span>
<span class="source-line-no">4378</span><span id="line-4378"> @Test</span>
<span class="source-line-no">4379</span><span id="line-4379"> public void testScannerOperationId() throws IOException {</span>
<span class="source-line-no">4380</span><span id="line-4380"> region = initHRegion(tableName, method, CONF, COLUMN_FAMILY_BYTES);</span>
<span class="source-line-no">4381</span><span id="line-4381"> Scan scan = new Scan();</span>
<span class="source-line-no">4382</span><span id="line-4382"> try (RegionScanner scanner = region.getScanner(scan)) {</span>
<span class="source-line-no">4383</span><span id="line-4383"> assertNull(scanner.getOperationId());</span>
<span class="source-line-no">4384</span><span id="line-4384"> }</span>
<span class="source-line-no">4385</span><span id="line-4385"></span>
<span class="source-line-no">4386</span><span id="line-4386"> String operationId = "test_operation_id_0101";</span>
<span class="source-line-no">4387</span><span id="line-4387"> scan = new Scan().setId(operationId);</span>
<span class="source-line-no">4388</span><span id="line-4388"> try (RegionScanner scanner = region.getScanner(scan)) {</span>
<span class="source-line-no">4389</span><span id="line-4389"> assertEquals(operationId, scanner.getOperationId());</span>
<span class="source-line-no">4390</span><span id="line-4390"> }</span>
<span class="source-line-no">4391</span><span id="line-4391"></span>
<span class="source-line-no">4392</span><span id="line-4392"> HBaseTestingUtil.closeRegionAndWAL(this.region);</span>
<span class="source-line-no">4393</span><span id="line-4393"> }</span>
<span class="source-line-no">4394</span><span id="line-4394"></span>
<span class="source-line-no">4395</span><span id="line-4395"> /**</span>
<span class="source-line-no">4396</span><span id="line-4396"> * Write an HFile block full with Cells whose qualifier that are identical between 0 and</span>
<span class="source-line-no">4397</span><span id="line-4397"> * Short.MAX_VALUE. See HBASE-13329.</span>
<span class="source-line-no">4398</span><span id="line-4398"> */</span>
<span class="source-line-no">4399</span><span id="line-4399"> @Test</span>
<span class="source-line-no">4400</span><span id="line-4400"> public void testLongQualifier() throws Exception {</span>
<span class="source-line-no">4401</span><span id="line-4401"> byte[] family = Bytes.toBytes("family");</span>
<span class="source-line-no">4402</span><span id="line-4402"> this.region = initHRegion(tableName, method, CONF, family);</span>
<span class="source-line-no">4403</span><span id="line-4403"> byte[] q = new byte[Short.MAX_VALUE + 2];</span>
<span class="source-line-no">4404</span><span id="line-4404"> Arrays.fill(q, 0, q.length - 1, (byte) 42);</span>
<span class="source-line-no">4405</span><span id="line-4405"> for (byte i = 0; i &lt; 10; i++) {</span>
<span class="source-line-no">4406</span><span id="line-4406"> Put p = new Put(Bytes.toBytes("row"));</span>
<span class="source-line-no">4407</span><span id="line-4407"> // qualifiers that differ past Short.MAX_VALUE</span>
<span class="source-line-no">4408</span><span id="line-4408"> q[q.length - 1] = i;</span>
<span class="source-line-no">4409</span><span id="line-4409"> p.addColumn(family, q, q);</span>
<span class="source-line-no">4410</span><span id="line-4410"> region.put(p);</span>
<span class="source-line-no">4411</span><span id="line-4411"> }</span>
<span class="source-line-no">4412</span><span id="line-4412"> region.flush(false);</span>
<span class="source-line-no">4413</span><span id="line-4413"> }</span>
<span class="source-line-no">4414</span><span id="line-4414"></span>
<span class="source-line-no">4415</span><span id="line-4415"> /**</span>
<span class="source-line-no">4416</span><span id="line-4416"> * Flushes the cache in a thread while scanning. The tests verify that the scan is coherent - e.g.</span>
<span class="source-line-no">4417</span><span id="line-4417"> * the returned results are always of the same or later update as the previous results. scan /</span>
<span class="source-line-no">4418</span><span id="line-4418"> * compact thread join</span>
<span class="source-line-no">4419</span><span id="line-4419"> */</span>
<span class="source-line-no">4420</span><span id="line-4420"> @Test</span>
<span class="source-line-no">4421</span><span id="line-4421"> public void testFlushCacheWhileScanning() throws IOException, InterruptedException {</span>
<span class="source-line-no">4422</span><span id="line-4422"> byte[] family = Bytes.toBytes("family");</span>
<span class="source-line-no">4423</span><span id="line-4423"> int numRows = 1000;</span>
<span class="source-line-no">4424</span><span id="line-4424"> int flushAndScanInterval = 10;</span>
<span class="source-line-no">4425</span><span id="line-4425"> int compactInterval = 10 * flushAndScanInterval;</span>
<span class="source-line-no">4426</span><span id="line-4426"></span>
<span class="source-line-no">4427</span><span id="line-4427"> this.region = initHRegion(tableName, method, CONF, family);</span>
<span class="source-line-no">4428</span><span id="line-4428"> FlushThread flushThread = new FlushThread();</span>
<span class="source-line-no">4429</span><span id="line-4429"> try {</span>
<span class="source-line-no">4430</span><span id="line-4430"> flushThread.start();</span>
<span class="source-line-no">4431</span><span id="line-4431"></span>
<span class="source-line-no">4432</span><span id="line-4432"> Scan scan = new Scan();</span>
<span class="source-line-no">4433</span><span id="line-4433"> scan.addFamily(family);</span>
<span class="source-line-no">4434</span><span id="line-4434"> scan.setFilter(new SingleColumnValueFilter(family, qual1, CompareOperator.EQUAL,</span>
<span class="source-line-no">4435</span><span id="line-4435"> new BinaryComparator(Bytes.toBytes(5L))));</span>
<span class="source-line-no">4436</span><span id="line-4436"></span>
<span class="source-line-no">4437</span><span id="line-4437"> int expectedCount = 0;</span>
<span class="source-line-no">4438</span><span id="line-4438"> List&lt;Cell&gt; res = new ArrayList&lt;&gt;();</span>
<span class="source-line-no">4439</span><span id="line-4439"></span>
<span class="source-line-no">4440</span><span id="line-4440"> boolean toggle = true;</span>
<span class="source-line-no">4441</span><span id="line-4441"> for (long i = 0; i &lt; numRows; i++) {</span>
<span class="source-line-no">4442</span><span id="line-4442"> Put put = new Put(Bytes.toBytes(i));</span>
<span class="source-line-no">4443</span><span id="line-4443"> put.setDurability(Durability.SKIP_WAL);</span>
<span class="source-line-no">4444</span><span id="line-4444"> put.addColumn(family, qual1, Bytes.toBytes(i % 10));</span>
<span class="source-line-no">4445</span><span id="line-4445"> region.put(put);</span>
<span class="source-line-no">4446</span><span id="line-4446"></span>
<span class="source-line-no">4447</span><span id="line-4447"> if (i != 0 &amp;&amp; i % compactInterval == 0) {</span>
<span class="source-line-no">4448</span><span id="line-4448"> LOG.debug("iteration = " + i + " ts=" + EnvironmentEdgeManager.currentTime());</span>
<span class="source-line-no">4449</span><span id="line-4449"> region.compact(true);</span>
<span class="source-line-no">4450</span><span id="line-4450"> }</span>
<span class="source-line-no">4451</span><span id="line-4451"></span>
<span class="source-line-no">4452</span><span id="line-4452"> if (i % 10 == 5L) {</span>
<span class="source-line-no">4453</span><span id="line-4453"> expectedCount++;</span>
<span class="source-line-no">4454</span><span id="line-4454"> }</span>
<span class="source-line-no">4455</span><span id="line-4455"></span>
<span class="source-line-no">4456</span><span id="line-4456"> if (i != 0 &amp;&amp; i % flushAndScanInterval == 0) {</span>
<span class="source-line-no">4457</span><span id="line-4457"> res.clear();</span>
<span class="source-line-no">4458</span><span id="line-4458"> try (InternalScanner scanner = region.getScanner(scan)) {</span>
<span class="source-line-no">4459</span><span id="line-4459"> if (toggle) {</span>
<span class="source-line-no">4460</span><span id="line-4460"> flushThread.flush();</span>
<span class="source-line-no">4461</span><span id="line-4461"> }</span>
<span class="source-line-no">4462</span><span id="line-4462"> while (scanner.next(res)) {</span>
<span class="source-line-no">4463</span><span id="line-4463"> // ignore</span>
<span class="source-line-no">4464</span><span id="line-4464"> }</span>
<span class="source-line-no">4465</span><span id="line-4465"> }</span>
<span class="source-line-no">4466</span><span id="line-4466"> if (!toggle) {</span>
<span class="source-line-no">4467</span><span id="line-4467"> flushThread.flush();</span>
<span class="source-line-no">4468</span><span id="line-4468"> }</span>
<span class="source-line-no">4469</span><span id="line-4469"> assertEquals(</span>
<span class="source-line-no">4470</span><span id="line-4470"> "toggle=" + toggle + "i=" + i + " ts=" + EnvironmentEdgeManager.currentTime(),</span>
<span class="source-line-no">4471</span><span id="line-4471"> expectedCount, res.size());</span>
<span class="source-line-no">4472</span><span id="line-4472"> toggle = !toggle;</span>
<span class="source-line-no">4473</span><span id="line-4473"> }</span>
<span class="source-line-no">4474</span><span id="line-4474"> }</span>
<span class="source-line-no">4475</span><span id="line-4475"></span>
<span class="source-line-no">4476</span><span id="line-4476"> } finally {</span>
<span class="source-line-no">4477</span><span id="line-4477"> try {</span>
<span class="source-line-no">4478</span><span id="line-4478"> flushThread.done();</span>
<span class="source-line-no">4479</span><span id="line-4479"> flushThread.join();</span>
<span class="source-line-no">4480</span><span id="line-4480"> flushThread.checkNoError();</span>
<span class="source-line-no">4481</span><span id="line-4481"> } catch (InterruptedException ie) {</span>
<span class="source-line-no">4482</span><span id="line-4482"> LOG.warn("Caught exception when joining with flushThread", ie);</span>
<span class="source-line-no">4483</span><span id="line-4483"> }</span>
<span class="source-line-no">4484</span><span id="line-4484"> HBaseTestingUtil.closeRegionAndWAL(this.region);</span>
<span class="source-line-no">4485</span><span id="line-4485"> this.region = null;</span>
<span class="source-line-no">4486</span><span id="line-4486"> }</span>
<span class="source-line-no">4487</span><span id="line-4487"> }</span>
<span class="source-line-no">4488</span><span id="line-4488"></span>
<span class="source-line-no">4489</span><span id="line-4489"> protected class FlushThread extends Thread {</span>
<span class="source-line-no">4490</span><span id="line-4490"> private volatile boolean done;</span>
<span class="source-line-no">4491</span><span id="line-4491"> private Throwable error = null;</span>
<span class="source-line-no">4492</span><span id="line-4492"></span>
<span class="source-line-no">4493</span><span id="line-4493"> FlushThread() {</span>
<span class="source-line-no">4494</span><span id="line-4494"> super("FlushThread");</span>
<span class="source-line-no">4495</span><span id="line-4495"> }</span>
<span class="source-line-no">4496</span><span id="line-4496"></span>
<span class="source-line-no">4497</span><span id="line-4497"> public void done() {</span>
<span class="source-line-no">4498</span><span id="line-4498"> done = true;</span>
<span class="source-line-no">4499</span><span id="line-4499"> synchronized (this) {</span>
<span class="source-line-no">4500</span><span id="line-4500"> interrupt();</span>
<span class="source-line-no">4501</span><span id="line-4501"> }</span>
<span class="source-line-no">4502</span><span id="line-4502"> }</span>
<span class="source-line-no">4503</span><span id="line-4503"></span>
<span class="source-line-no">4504</span><span id="line-4504"> public void checkNoError() {</span>
<span class="source-line-no">4505</span><span id="line-4505"> if (error != null) {</span>
<span class="source-line-no">4506</span><span id="line-4506"> assertNull(error);</span>
<span class="source-line-no">4507</span><span id="line-4507"> }</span>
<span class="source-line-no">4508</span><span id="line-4508"> }</span>
<span class="source-line-no">4509</span><span id="line-4509"></span>
<span class="source-line-no">4510</span><span id="line-4510"> @Override</span>
<span class="source-line-no">4511</span><span id="line-4511"> public void run() {</span>
<span class="source-line-no">4512</span><span id="line-4512"> done = false;</span>
<span class="source-line-no">4513</span><span id="line-4513"> while (!done) {</span>
<span class="source-line-no">4514</span><span id="line-4514"> synchronized (this) {</span>
<span class="source-line-no">4515</span><span id="line-4515"> try {</span>
<span class="source-line-no">4516</span><span id="line-4516"> wait();</span>
<span class="source-line-no">4517</span><span id="line-4517"> } catch (InterruptedException ignored) {</span>
<span class="source-line-no">4518</span><span id="line-4518"> if (done) {</span>
<span class="source-line-no">4519</span><span id="line-4519"> break;</span>
<span class="source-line-no">4520</span><span id="line-4520"> }</span>
<span class="source-line-no">4521</span><span id="line-4521"> }</span>
<span class="source-line-no">4522</span><span id="line-4522"> }</span>
<span class="source-line-no">4523</span><span id="line-4523"> try {</span>
<span class="source-line-no">4524</span><span id="line-4524"> region.flush(true);</span>
<span class="source-line-no">4525</span><span id="line-4525"> } catch (IOException e) {</span>
<span class="source-line-no">4526</span><span id="line-4526"> if (!done) {</span>
<span class="source-line-no">4527</span><span id="line-4527"> LOG.error("Error while flushing cache", e);</span>
<span class="source-line-no">4528</span><span id="line-4528"> error = e;</span>
<span class="source-line-no">4529</span><span id="line-4529"> }</span>
<span class="source-line-no">4530</span><span id="line-4530"> break;</span>
<span class="source-line-no">4531</span><span id="line-4531"> } catch (Throwable t) {</span>
<span class="source-line-no">4532</span><span id="line-4532"> LOG.error("Uncaught exception", t);</span>
<span class="source-line-no">4533</span><span id="line-4533"> throw t;</span>
<span class="source-line-no">4534</span><span id="line-4534"> }</span>
<span class="source-line-no">4535</span><span id="line-4535"> }</span>
<span class="source-line-no">4536</span><span id="line-4536"> }</span>
<span class="source-line-no">4537</span><span id="line-4537"></span>
<span class="source-line-no">4538</span><span id="line-4538"> public void flush() {</span>
<span class="source-line-no">4539</span><span id="line-4539"> synchronized (this) {</span>
<span class="source-line-no">4540</span><span id="line-4540"> notify();</span>
<span class="source-line-no">4541</span><span id="line-4541"> }</span>
<span class="source-line-no">4542</span><span id="line-4542"> }</span>
<span class="source-line-no">4543</span><span id="line-4543"> }</span>
<span class="source-line-no">4544</span><span id="line-4544"></span>
<span class="source-line-no">4545</span><span id="line-4545"> /**</span>
<span class="source-line-no">4546</span><span id="line-4546"> * So can be overridden in subclasses.</span>
<span class="source-line-no">4547</span><span id="line-4547"> */</span>
<span class="source-line-no">4548</span><span id="line-4548"> protected int getNumQualifiersForTestWritesWhileScanning() {</span>
<span class="source-line-no">4549</span><span id="line-4549"> return 100;</span>
<span class="source-line-no">4550</span><span id="line-4550"> }</span>
<span class="source-line-no">4551</span><span id="line-4551"></span>
<span class="source-line-no">4552</span><span id="line-4552"> /**</span>
<span class="source-line-no">4553</span><span id="line-4553"> * So can be overridden in subclasses.</span>
<span class="source-line-no">4554</span><span id="line-4554"> */</span>
<span class="source-line-no">4555</span><span id="line-4555"> protected int getTestCountForTestWritesWhileScanning() {</span>
<span class="source-line-no">4556</span><span id="line-4556"> return 100;</span>
<span class="source-line-no">4557</span><span id="line-4557"> }</span>
<span class="source-line-no">4558</span><span id="line-4558"></span>
<span class="source-line-no">4559</span><span id="line-4559"> /**</span>
<span class="source-line-no">4560</span><span id="line-4560"> * Writes very wide records and scans for the latest every time.. Flushes and compacts the region</span>
<span class="source-line-no">4561</span><span id="line-4561"> * every now and then to keep things realistic. by flush / scan / compaction when joining threads</span>
<span class="source-line-no">4562</span><span id="line-4562"> */</span>
<span class="source-line-no">4563</span><span id="line-4563"> @Test</span>
<span class="source-line-no">4564</span><span id="line-4564"> public void testWritesWhileScanning() throws IOException, InterruptedException {</span>
<span class="source-line-no">4565</span><span id="line-4565"> int testCount = getTestCountForTestWritesWhileScanning();</span>
<span class="source-line-no">4566</span><span id="line-4566"> int numRows = 1;</span>
<span class="source-line-no">4567</span><span id="line-4567"> int numFamilies = 10;</span>
<span class="source-line-no">4568</span><span id="line-4568"> int numQualifiers = getNumQualifiersForTestWritesWhileScanning();</span>
<span class="source-line-no">4569</span><span id="line-4569"> int flushInterval = 7;</span>
<span class="source-line-no">4570</span><span id="line-4570"> int compactInterval = 5 * flushInterval;</span>
<span class="source-line-no">4571</span><span id="line-4571"> byte[][] families = new byte[numFamilies][];</span>
<span class="source-line-no">4572</span><span id="line-4572"> for (int i = 0; i &lt; numFamilies; i++) {</span>
<span class="source-line-no">4573</span><span id="line-4573"> families[i] = Bytes.toBytes("family" + i);</span>
<span class="source-line-no">4574</span><span id="line-4574"> }</span>
<span class="source-line-no">4575</span><span id="line-4575"> byte[][] qualifiers = new byte[numQualifiers][];</span>
<span class="source-line-no">4576</span><span id="line-4576"> for (int i = 0; i &lt; numQualifiers; i++) {</span>
<span class="source-line-no">4577</span><span id="line-4577"> qualifiers[i] = Bytes.toBytes("qual" + i);</span>
<span class="source-line-no">4578</span><span id="line-4578"> }</span>
<span class="source-line-no">4579</span><span id="line-4579"></span>
<span class="source-line-no">4580</span><span id="line-4580"> this.region = initHRegion(tableName, method, CONF, families);</span>
<span class="source-line-no">4581</span><span id="line-4581"> FlushThread flushThread = new FlushThread();</span>
<span class="source-line-no">4582</span><span id="line-4582"> PutThread putThread = new PutThread(numRows, families, qualifiers);</span>
<span class="source-line-no">4583</span><span id="line-4583"> try {</span>
<span class="source-line-no">4584</span><span id="line-4584"> putThread.start();</span>
<span class="source-line-no">4585</span><span id="line-4585"> putThread.waitForFirstPut();</span>
<span class="source-line-no">4586</span><span id="line-4586"></span>
<span class="source-line-no">4587</span><span id="line-4587"> flushThread.start();</span>
<span class="source-line-no">4588</span><span id="line-4588"></span>
<span class="source-line-no">4589</span><span id="line-4589"> Scan scan = new Scan().withStartRow(Bytes.toBytes("row0")).withStopRow(Bytes.toBytes("row1"));</span>
<span class="source-line-no">4590</span><span id="line-4590"></span>
<span class="source-line-no">4591</span><span id="line-4591"> int expectedCount = numFamilies * numQualifiers;</span>
<span class="source-line-no">4592</span><span id="line-4592"> List&lt;Cell&gt; res = new ArrayList&lt;&gt;();</span>
<span class="source-line-no">4593</span><span id="line-4593"></span>
<span class="source-line-no">4594</span><span id="line-4594"> long prevTimestamp = 0L;</span>
<span class="source-line-no">4595</span><span id="line-4595"> for (int i = 0; i &lt; testCount; i++) {</span>
<span class="source-line-no">4596</span><span id="line-4596"></span>
<span class="source-line-no">4597</span><span id="line-4597"> if (i != 0 &amp;&amp; i % compactInterval == 0) {</span>
<span class="source-line-no">4598</span><span id="line-4598"> region.compact(true);</span>
<span class="source-line-no">4599</span><span id="line-4599"> for (HStore store : region.getStores()) {</span>
<span class="source-line-no">4600</span><span id="line-4600"> store.closeAndArchiveCompactedFiles();</span>
<span class="source-line-no">4601</span><span id="line-4601"> }</span>
<span class="source-line-no">4602</span><span id="line-4602"> }</span>
<span class="source-line-no">4603</span><span id="line-4603"></span>
<span class="source-line-no">4604</span><span id="line-4604"> if (i != 0 &amp;&amp; i % flushInterval == 0) {</span>
<span class="source-line-no">4605</span><span id="line-4605"> flushThread.flush();</span>
<span class="source-line-no">4606</span><span id="line-4606"> }</span>
<span class="source-line-no">4607</span><span id="line-4607"></span>
<span class="source-line-no">4608</span><span id="line-4608"> boolean previousEmpty = res.isEmpty();</span>
<span class="source-line-no">4609</span><span id="line-4609"> res.clear();</span>
<span class="source-line-no">4610</span><span id="line-4610"> try (InternalScanner scanner = region.getScanner(scan)) {</span>
<span class="source-line-no">4611</span><span id="line-4611"> boolean moreRows;</span>
<span class="source-line-no">4612</span><span id="line-4612"> do {</span>
<span class="source-line-no">4613</span><span id="line-4613"> moreRows = scanner.next(res);</span>
<span class="source-line-no">4614</span><span id="line-4614"> } while (moreRows);</span>
<span class="source-line-no">4615</span><span id="line-4615"> }</span>
<span class="source-line-no">4616</span><span id="line-4616"> if (!res.isEmpty() || !previousEmpty || i &gt; compactInterval) {</span>
<span class="source-line-no">4617</span><span id="line-4617"> assertEquals("i=" + i, expectedCount, res.size());</span>
<span class="source-line-no">4618</span><span id="line-4618"> long timestamp = res.get(0).getTimestamp();</span>
<span class="source-line-no">4619</span><span id="line-4619"> assertTrue("Timestamps were broke: " + timestamp + " prev: " + prevTimestamp,</span>
<span class="source-line-no">4620</span><span id="line-4620"> timestamp &gt;= prevTimestamp);</span>
<span class="source-line-no">4621</span><span id="line-4621"> prevTimestamp = timestamp;</span>
<span class="source-line-no">4622</span><span id="line-4622"> }</span>
<span class="source-line-no">4623</span><span id="line-4623"> }</span>
<span class="source-line-no">4624</span><span id="line-4624"></span>
<span class="source-line-no">4625</span><span id="line-4625"> putThread.done();</span>
<span class="source-line-no">4626</span><span id="line-4626"></span>
<span class="source-line-no">4627</span><span id="line-4627"> region.flush(true);</span>
<span class="source-line-no">4628</span><span id="line-4628"></span>
<span class="source-line-no">4629</span><span id="line-4629"> } finally {</span>
<span class="source-line-no">4630</span><span id="line-4630"> try {</span>
<span class="source-line-no">4631</span><span id="line-4631"> flushThread.done();</span>
<span class="source-line-no">4632</span><span id="line-4632"> flushThread.join();</span>
<span class="source-line-no">4633</span><span id="line-4633"> flushThread.checkNoError();</span>
<span class="source-line-no">4634</span><span id="line-4634"></span>
<span class="source-line-no">4635</span><span id="line-4635"> putThread.join();</span>
<span class="source-line-no">4636</span><span id="line-4636"> putThread.checkNoError();</span>
<span class="source-line-no">4637</span><span id="line-4637"> } catch (InterruptedException ie) {</span>
<span class="source-line-no">4638</span><span id="line-4638"> LOG.warn("Caught exception when joining with flushThread", ie);</span>
<span class="source-line-no">4639</span><span id="line-4639"> }</span>
<span class="source-line-no">4640</span><span id="line-4640"></span>
<span class="source-line-no">4641</span><span id="line-4641"> try {</span>
<span class="source-line-no">4642</span><span id="line-4642"> HBaseTestingUtil.closeRegionAndWAL(this.region);</span>
<span class="source-line-no">4643</span><span id="line-4643"> } catch (DroppedSnapshotException dse) {</span>
<span class="source-line-no">4644</span><span id="line-4644"> // We could get this on way out because we interrupt the background flusher and it could</span>
<span class="source-line-no">4645</span><span id="line-4645"> // fail anywhere causing a DSE over in the background flusher... only it is not properly</span>
<span class="source-line-no">4646</span><span id="line-4646"> // dealt with so could still be memory hanging out when we get to here -- memory we can't</span>
<span class="source-line-no">4647</span><span id="line-4647"> // flush because the accounting is 'off' since original DSE.</span>
<span class="source-line-no">4648</span><span id="line-4648"> }</span>
<span class="source-line-no">4649</span><span id="line-4649"> this.region = null;</span>
<span class="source-line-no">4650</span><span id="line-4650"> }</span>
<span class="source-line-no">4651</span><span id="line-4651"> }</span>
<span class="source-line-no">4652</span><span id="line-4652"></span>
<span class="source-line-no">4653</span><span id="line-4653"> @Test</span>
<span class="source-line-no">4654</span><span id="line-4654"> public void testCloseAndArchiveCompactedFiles() throws IOException {</span>
<span class="source-line-no">4655</span><span id="line-4655"> byte[] CF1 = Bytes.toBytes("CF1");</span>
<span class="source-line-no">4656</span><span id="line-4656"> byte[] CF2 = Bytes.toBytes("CF2");</span>
<span class="source-line-no">4657</span><span id="line-4657"> this.region = initHRegion(tableName, method, CONF, CF1, CF2);</span>
<span class="source-line-no">4658</span><span id="line-4658"> for (int i = 0; i &lt; 2; i++) {</span>
<span class="source-line-no">4659</span><span id="line-4659"> int index = i;</span>
<span class="source-line-no">4660</span><span id="line-4660"> Put put =</span>
<span class="source-line-no">4661</span><span id="line-4661"> new Put(Bytes.toBytes(index)).addColumn(CF1, Bytes.toBytes("q"), Bytes.toBytes(index));</span>
<span class="source-line-no">4662</span><span id="line-4662"> region.put(put);</span>
<span class="source-line-no">4663</span><span id="line-4663"> region.flush(true);</span>
<span class="source-line-no">4664</span><span id="line-4664"> }</span>
<span class="source-line-no">4665</span><span id="line-4665"></span>
<span class="source-line-no">4666</span><span id="line-4666"> region.compact(true);</span>
<span class="source-line-no">4667</span><span id="line-4667"></span>
<span class="source-line-no">4668</span><span id="line-4668"> HStore store1 = region.getStore(CF1);</span>
<span class="source-line-no">4669</span><span id="line-4669"> HStore store2 = region.getStore(CF2);</span>
<span class="source-line-no">4670</span><span id="line-4670"> store1.closeAndArchiveCompactedFiles();</span>
<span class="source-line-no">4671</span><span id="line-4671"> store2.closeAndArchiveCompactedFiles();</span>
<span class="source-line-no">4672</span><span id="line-4672"></span>
<span class="source-line-no">4673</span><span id="line-4673"> int storefilesCount = region.getStores().stream().mapToInt(Store::getStorefilesCount).sum();</span>
<span class="source-line-no">4674</span><span id="line-4674"> assertTrue(storefilesCount == 1);</span>
<span class="source-line-no">4675</span><span id="line-4675"></span>
<span class="source-line-no">4676</span><span id="line-4676"> FileSystem fs = region.getRegionFileSystem().getFileSystem();</span>
<span class="source-line-no">4677</span><span id="line-4677"> Configuration conf = region.getReadOnlyConfiguration();</span>
<span class="source-line-no">4678</span><span id="line-4678"> RegionInfo regionInfo = region.getRegionInfo();</span>
<span class="source-line-no">4679</span><span id="line-4679"> Path store1ArchiveDir = HFileArchiveUtil.getStoreArchivePath(conf, regionInfo, CF1);</span>
<span class="source-line-no">4680</span><span id="line-4680"> assertTrue(fs.exists(store1ArchiveDir));</span>
<span class="source-line-no">4681</span><span id="line-4681"> // The archived dir of CF2 does not exist because this column family has no data at all</span>
<span class="source-line-no">4682</span><span id="line-4682"> Path store2ArchiveDir = HFileArchiveUtil.getStoreArchivePath(conf, regionInfo, CF2);</span>
<span class="source-line-no">4683</span><span id="line-4683"> assertFalse(fs.exists(store2ArchiveDir));</span>
<span class="source-line-no">4684</span><span id="line-4684"> }</span>
<span class="source-line-no">4685</span><span id="line-4685"></span>
<span class="source-line-no">4686</span><span id="line-4686"> protected class PutThread extends Thread {</span>
<span class="source-line-no">4687</span><span id="line-4687"> private volatile boolean done;</span>
<span class="source-line-no">4688</span><span id="line-4688"> private volatile int numPutsFinished = 0;</span>
<span class="source-line-no">4689</span><span id="line-4689"></span>
<span class="source-line-no">4690</span><span id="line-4690"> private Throwable error = null;</span>
<span class="source-line-no">4691</span><span id="line-4691"> private int numRows;</span>
<span class="source-line-no">4692</span><span id="line-4692"> private byte[][] families;</span>
<span class="source-line-no">4693</span><span id="line-4693"> private byte[][] qualifiers;</span>
<span class="source-line-no">4694</span><span id="line-4694"></span>
<span class="source-line-no">4695</span><span id="line-4695"> private PutThread(int numRows, byte[][] families, byte[][] qualifiers) {</span>
<span class="source-line-no">4696</span><span id="line-4696"> super("PutThread");</span>
<span class="source-line-no">4697</span><span id="line-4697"> this.numRows = numRows;</span>
<span class="source-line-no">4698</span><span id="line-4698"> this.families = families;</span>
<span class="source-line-no">4699</span><span id="line-4699"> this.qualifiers = qualifiers;</span>
<span class="source-line-no">4700</span><span id="line-4700"> }</span>
<span class="source-line-no">4701</span><span id="line-4701"></span>
<span class="source-line-no">4702</span><span id="line-4702"> /**</span>
<span class="source-line-no">4703</span><span id="line-4703"> * Block calling thread until this instance of PutThread has put at least one row.</span>
<span class="source-line-no">4704</span><span id="line-4704"> */</span>
<span class="source-line-no">4705</span><span id="line-4705"> public void waitForFirstPut() throws InterruptedException {</span>
<span class="source-line-no">4706</span><span id="line-4706"> // wait until put thread actually puts some data</span>
<span class="source-line-no">4707</span><span id="line-4707"> while (isAlive() &amp;&amp; numPutsFinished == 0) {</span>
<span class="source-line-no">4708</span><span id="line-4708"> checkNoError();</span>
<span class="source-line-no">4709</span><span id="line-4709"> Thread.sleep(50);</span>
<span class="source-line-no">4710</span><span id="line-4710"> }</span>
<span class="source-line-no">4711</span><span id="line-4711"> }</span>
<span class="source-line-no">4712</span><span id="line-4712"></span>
<span class="source-line-no">4713</span><span id="line-4713"> public void done() {</span>
<span class="source-line-no">4714</span><span id="line-4714"> done = true;</span>
<span class="source-line-no">4715</span><span id="line-4715"> synchronized (this) {</span>
<span class="source-line-no">4716</span><span id="line-4716"> interrupt();</span>
<span class="source-line-no">4717</span><span id="line-4717"> }</span>
<span class="source-line-no">4718</span><span id="line-4718"> }</span>
<span class="source-line-no">4719</span><span id="line-4719"></span>
<span class="source-line-no">4720</span><span id="line-4720"> public void checkNoError() {</span>
<span class="source-line-no">4721</span><span id="line-4721"> if (error != null) {</span>
<span class="source-line-no">4722</span><span id="line-4722"> assertNull(error);</span>
<span class="source-line-no">4723</span><span id="line-4723"> }</span>
<span class="source-line-no">4724</span><span id="line-4724"> }</span>
<span class="source-line-no">4725</span><span id="line-4725"></span>
<span class="source-line-no">4726</span><span id="line-4726"> @Override</span>
<span class="source-line-no">4727</span><span id="line-4727"> public void run() {</span>
<span class="source-line-no">4728</span><span id="line-4728"> done = false;</span>
<span class="source-line-no">4729</span><span id="line-4729"> while (!done) {</span>
<span class="source-line-no">4730</span><span id="line-4730"> try {</span>
<span class="source-line-no">4731</span><span id="line-4731"> for (int r = 0; r &lt; numRows; r++) {</span>
<span class="source-line-no">4732</span><span id="line-4732"> byte[] row = Bytes.toBytes("row" + r);</span>
<span class="source-line-no">4733</span><span id="line-4733"> Put put = new Put(row);</span>
<span class="source-line-no">4734</span><span id="line-4734"> put.setDurability(Durability.SKIP_WAL);</span>
<span class="source-line-no">4735</span><span id="line-4735"> byte[] value = Bytes.toBytes(String.valueOf(numPutsFinished));</span>
<span class="source-line-no">4736</span><span id="line-4736"> for (byte[] family : families) {</span>
<span class="source-line-no">4737</span><span id="line-4737"> for (byte[] qualifier : qualifiers) {</span>
<span class="source-line-no">4738</span><span id="line-4738"> put.addColumn(family, qualifier, numPutsFinished, value);</span>
<span class="source-line-no">4739</span><span id="line-4739"> }</span>
<span class="source-line-no">4740</span><span id="line-4740"> }</span>
<span class="source-line-no">4741</span><span id="line-4741"> region.put(put);</span>
<span class="source-line-no">4742</span><span id="line-4742"> numPutsFinished++;</span>
<span class="source-line-no">4743</span><span id="line-4743"> if (numPutsFinished &gt; 0 &amp;&amp; numPutsFinished % 47 == 0) {</span>
<span class="source-line-no">4744</span><span id="line-4744"> LOG.debug("put iteration = {}", numPutsFinished);</span>
<span class="source-line-no">4745</span><span id="line-4745"> Delete delete = new Delete(row, (long) numPutsFinished - 30);</span>
<span class="source-line-no">4746</span><span id="line-4746"> region.delete(delete);</span>
<span class="source-line-no">4747</span><span id="line-4747"> }</span>
<span class="source-line-no">4748</span><span id="line-4748"> numPutsFinished++;</span>
<span class="source-line-no">4749</span><span id="line-4749"> }</span>
<span class="source-line-no">4750</span><span id="line-4750"> } catch (InterruptedIOException e) {</span>
<span class="source-line-no">4751</span><span id="line-4751"> // This is fine. It means we are done, or didn't get the lock on time</span>
<span class="source-line-no">4752</span><span id="line-4752"> LOG.info("Interrupted", e);</span>
<span class="source-line-no">4753</span><span id="line-4753"> } catch (IOException e) {</span>
<span class="source-line-no">4754</span><span id="line-4754"> LOG.error("Error while putting records", e);</span>
<span class="source-line-no">4755</span><span id="line-4755"> error = e;</span>
<span class="source-line-no">4756</span><span id="line-4756"> break;</span>
<span class="source-line-no">4757</span><span id="line-4757"> }</span>
<span class="source-line-no">4758</span><span id="line-4758"> }</span>
<span class="source-line-no">4759</span><span id="line-4759"></span>
<span class="source-line-no">4760</span><span id="line-4760"> }</span>
<span class="source-line-no">4761</span><span id="line-4761"></span>
<span class="source-line-no">4762</span><span id="line-4762"> }</span>
<span class="source-line-no">4763</span><span id="line-4763"></span>
<span class="source-line-no">4764</span><span id="line-4764"> /**</span>
<span class="source-line-no">4765</span><span id="line-4765"> * Writes very wide records and gets the latest row every time.. Flushes and compacts the region</span>
<span class="source-line-no">4766</span><span id="line-4766"> * aggressivly to catch issues. by flush / scan / compaction when joining threads</span>
<span class="source-line-no">4767</span><span id="line-4767"> */</span>
<span class="source-line-no">4768</span><span id="line-4768"> @Test</span>
<span class="source-line-no">4769</span><span id="line-4769"> public void testWritesWhileGetting() throws Exception {</span>
<span class="source-line-no">4770</span><span id="line-4770"> int testCount = 50;</span>
<span class="source-line-no">4771</span><span id="line-4771"> int numRows = 1;</span>
<span class="source-line-no">4772</span><span id="line-4772"> int numFamilies = 10;</span>
<span class="source-line-no">4773</span><span id="line-4773"> int numQualifiers = 100;</span>
<span class="source-line-no">4774</span><span id="line-4774"> int compactInterval = 100;</span>
<span class="source-line-no">4775</span><span id="line-4775"> byte[][] families = new byte[numFamilies][];</span>
<span class="source-line-no">4776</span><span id="line-4776"> for (int i = 0; i &lt; numFamilies; i++) {</span>
<span class="source-line-no">4777</span><span id="line-4777"> families[i] = Bytes.toBytes("family" + i);</span>
<span class="source-line-no">4778</span><span id="line-4778"> }</span>
<span class="source-line-no">4779</span><span id="line-4779"> byte[][] qualifiers = new byte[numQualifiers][];</span>
<span class="source-line-no">4780</span><span id="line-4780"> for (int i = 0; i &lt; numQualifiers; i++) {</span>
<span class="source-line-no">4781</span><span id="line-4781"> qualifiers[i] = Bytes.toBytes("qual" + i);</span>
<span class="source-line-no">4782</span><span id="line-4782"> }</span>
<span class="source-line-no">4783</span><span id="line-4783"></span>
<span class="source-line-no">4784</span><span id="line-4784"> // This test flushes constantly and can cause many files to be created,</span>
<span class="source-line-no">4785</span><span id="line-4785"> // possibly</span>
<span class="source-line-no">4786</span><span id="line-4786"> // extending over the ulimit. Make sure compactions are aggressive in</span>
<span class="source-line-no">4787</span><span id="line-4787"> // reducing</span>
<span class="source-line-no">4788</span><span id="line-4788"> // the number of HFiles created.</span>
<span class="source-line-no">4789</span><span id="line-4789"> Configuration conf = HBaseConfiguration.create(CONF);</span>
<span class="source-line-no">4790</span><span id="line-4790"> conf.setInt("hbase.hstore.compaction.min", 1);</span>
<span class="source-line-no">4791</span><span id="line-4791"> conf.setInt("hbase.hstore.compaction.max", 1000);</span>
<span class="source-line-no">4792</span><span id="line-4792"> this.region = initHRegion(tableName, method, conf, families);</span>
<span class="source-line-no">4793</span><span id="line-4793"> PutThread putThread = null;</span>
<span class="source-line-no">4794</span><span id="line-4794"> MultithreadedTestUtil.TestContext ctx = new MultithreadedTestUtil.TestContext(conf);</span>
<span class="source-line-no">4795</span><span id="line-4795"> try {</span>
<span class="source-line-no">4796</span><span id="line-4796"> putThread = new PutThread(numRows, families, qualifiers);</span>
<span class="source-line-no">4797</span><span id="line-4797"> putThread.start();</span>
<span class="source-line-no">4798</span><span id="line-4798"> putThread.waitForFirstPut();</span>
<span class="source-line-no">4799</span><span id="line-4799"></span>
<span class="source-line-no">4800</span><span id="line-4800"> // Add a thread that flushes as fast as possible</span>
<span class="source-line-no">4801</span><span id="line-4801"> ctx.addThread(new RepeatingTestThread(ctx) {</span>
<span class="source-line-no">4802</span><span id="line-4802"></span>
<span class="source-line-no">4803</span><span id="line-4803"> @Override</span>
<span class="source-line-no">4804</span><span id="line-4804"> public void doAnAction() throws Exception {</span>
<span class="source-line-no">4805</span><span id="line-4805"> region.flush(true);</span>
<span class="source-line-no">4806</span><span id="line-4806"> // Compact regularly to avoid creating too many files and exceeding</span>
<span class="source-line-no">4807</span><span id="line-4807"> // the ulimit.</span>
<span class="source-line-no">4808</span><span id="line-4808"> region.compact(false);</span>
<span class="source-line-no">4809</span><span id="line-4809"> for (HStore store : region.getStores()) {</span>
<span class="source-line-no">4810</span><span id="line-4810"> store.closeAndArchiveCompactedFiles();</span>
<span class="source-line-no">4811</span><span id="line-4811"> }</span>
<span class="source-line-no">4812</span><span id="line-4812"> }</span>
<span class="source-line-no">4813</span><span id="line-4813"> });</span>
<span class="source-line-no">4814</span><span id="line-4814"> ctx.startThreads();</span>
<span class="source-line-no">4815</span><span id="line-4815"></span>
<span class="source-line-no">4816</span><span id="line-4816"> Get get = new Get(Bytes.toBytes("row0"));</span>
<span class="source-line-no">4817</span><span id="line-4817"> Result result = null;</span>
<span class="source-line-no">4818</span><span id="line-4818"></span>
<span class="source-line-no">4819</span><span id="line-4819"> int expectedCount = numFamilies * numQualifiers;</span>
<span class="source-line-no">4820</span><span id="line-4820"></span>
<span class="source-line-no">4821</span><span id="line-4821"> long prevTimestamp = 0L;</span>
<span class="source-line-no">4822</span><span id="line-4822"> for (int i = 0; i &lt; testCount; i++) {</span>
<span class="source-line-no">4823</span><span id="line-4823"> LOG.info("testWritesWhileGetting verify turn " + i);</span>
<span class="source-line-no">4824</span><span id="line-4824"> boolean previousEmpty = result == null || result.isEmpty();</span>
<span class="source-line-no">4825</span><span id="line-4825"> result = region.get(get);</span>
<span class="source-line-no">4826</span><span id="line-4826"> if (!result.isEmpty() || !previousEmpty || i &gt; compactInterval) {</span>
<span class="source-line-no">4827</span><span id="line-4827"> assertEquals("i=" + i, expectedCount, result.size());</span>
<span class="source-line-no">4828</span><span id="line-4828"> // TODO this was removed, now what dangit?!</span>
<span class="source-line-no">4829</span><span id="line-4829"> // search looking for the qualifier in question?</span>
<span class="source-line-no">4830</span><span id="line-4830"> long timestamp = 0;</span>
<span class="source-line-no">4831</span><span id="line-4831"> for (Cell kv : result.rawCells()) {</span>
<span class="source-line-no">4832</span><span id="line-4832"> if (</span>
<span class="source-line-no">4833</span><span id="line-4833"> CellUtil.matchingFamily(kv, families[0])</span>
<span class="source-line-no">4834</span><span id="line-4834"> &amp;&amp; CellUtil.matchingQualifier(kv, qualifiers[0])</span>
<span class="source-line-no">4835</span><span id="line-4835"> ) {</span>
<span class="source-line-no">4836</span><span id="line-4836"> timestamp = kv.getTimestamp();</span>
<span class="source-line-no">4837</span><span id="line-4837"> }</span>
<span class="source-line-no">4838</span><span id="line-4838"> }</span>
<span class="source-line-no">4839</span><span id="line-4839"> assertTrue(timestamp &gt;= prevTimestamp);</span>
<span class="source-line-no">4840</span><span id="line-4840"> prevTimestamp = timestamp;</span>
<span class="source-line-no">4841</span><span id="line-4841"> Cell previousKV = null;</span>
<span class="source-line-no">4842</span><span id="line-4842"></span>
<span class="source-line-no">4843</span><span id="line-4843"> for (Cell kv : result.rawCells()) {</span>
<span class="source-line-no">4844</span><span id="line-4844"> byte[] thisValue = CellUtil.cloneValue(kv);</span>
<span class="source-line-no">4845</span><span id="line-4845"> if (previousKV != null) {</span>
<span class="source-line-no">4846</span><span id="line-4846"> if (Bytes.compareTo(CellUtil.cloneValue(previousKV), thisValue) != 0) {</span>
<span class="source-line-no">4847</span><span id="line-4847"> LOG.warn("These two KV should have the same value." + " Previous KV:" + previousKV</span>
<span class="source-line-no">4848</span><span id="line-4848"> + "(memStoreTS:" + previousKV.getSequenceId() + ")" + ", New KV: " + kv</span>
<span class="source-line-no">4849</span><span id="line-4849"> + "(memStoreTS:" + kv.getSequenceId() + ")");</span>
<span class="source-line-no">4850</span><span id="line-4850"> assertEquals(0, Bytes.compareTo(CellUtil.cloneValue(previousKV), thisValue));</span>
<span class="source-line-no">4851</span><span id="line-4851"> }</span>
<span class="source-line-no">4852</span><span id="line-4852"> }</span>
<span class="source-line-no">4853</span><span id="line-4853"> previousKV = kv;</span>
<span class="source-line-no">4854</span><span id="line-4854"> }</span>
<span class="source-line-no">4855</span><span id="line-4855"> }</span>
<span class="source-line-no">4856</span><span id="line-4856"> }</span>
<span class="source-line-no">4857</span><span id="line-4857"> } finally {</span>
<span class="source-line-no">4858</span><span id="line-4858"> if (putThread != null) putThread.done();</span>
<span class="source-line-no">4859</span><span id="line-4859"></span>
<span class="source-line-no">4860</span><span id="line-4860"> region.flush(true);</span>
<span class="source-line-no">4861</span><span id="line-4861"></span>
<span class="source-line-no">4862</span><span id="line-4862"> if (putThread != null) {</span>
<span class="source-line-no">4863</span><span id="line-4863"> putThread.join();</span>
<span class="source-line-no">4864</span><span id="line-4864"> putThread.checkNoError();</span>
<span class="source-line-no">4865</span><span id="line-4865"> }</span>
<span class="source-line-no">4866</span><span id="line-4866"></span>
<span class="source-line-no">4867</span><span id="line-4867"> ctx.stop();</span>
<span class="source-line-no">4868</span><span id="line-4868"> HBaseTestingUtil.closeRegionAndWAL(this.region);</span>
<span class="source-line-no">4869</span><span id="line-4869"> this.region = null;</span>
<span class="source-line-no">4870</span><span id="line-4870"> }</span>
<span class="source-line-no">4871</span><span id="line-4871"> }</span>
<span class="source-line-no">4872</span><span id="line-4872"></span>
<span class="source-line-no">4873</span><span id="line-4873"> @Test</span>
<span class="source-line-no">4874</span><span id="line-4874"> public void testHolesInMeta() throws Exception {</span>
<span class="source-line-no">4875</span><span id="line-4875"> byte[] family = Bytes.toBytes("family");</span>
<span class="source-line-no">4876</span><span id="line-4876"> this.region =</span>
<span class="source-line-no">4877</span><span id="line-4877"> initHRegion(tableName, Bytes.toBytes("x"), Bytes.toBytes("z"), method, CONF, false, family);</span>
<span class="source-line-no">4878</span><span id="line-4878"> byte[] rowNotServed = Bytes.toBytes("a");</span>
<span class="source-line-no">4879</span><span id="line-4879"> Get g = new Get(rowNotServed);</span>
<span class="source-line-no">4880</span><span id="line-4880"> try {</span>
<span class="source-line-no">4881</span><span id="line-4881"> region.get(g);</span>
<span class="source-line-no">4882</span><span id="line-4882"> fail();</span>
<span class="source-line-no">4883</span><span id="line-4883"> } catch (WrongRegionException x) {</span>
<span class="source-line-no">4884</span><span id="line-4884"> // OK</span>
<span class="source-line-no">4885</span><span id="line-4885"> }</span>
<span class="source-line-no">4886</span><span id="line-4886"> byte[] row = Bytes.toBytes("y");</span>
<span class="source-line-no">4887</span><span id="line-4887"> g = new Get(row);</span>
<span class="source-line-no">4888</span><span id="line-4888"> region.get(g);</span>
<span class="source-line-no">4889</span><span id="line-4889"> }</span>
<span class="source-line-no">4890</span><span id="line-4890"></span>
<span class="source-line-no">4891</span><span id="line-4891"> @Test</span>
<span class="source-line-no">4892</span><span id="line-4892"> public void testIndexesScanWithOneDeletedRow() throws IOException {</span>
<span class="source-line-no">4893</span><span id="line-4893"> byte[] family = Bytes.toBytes("family");</span>
<span class="source-line-no">4894</span><span id="line-4894"></span>
<span class="source-line-no">4895</span><span id="line-4895"> // Setting up region</span>
<span class="source-line-no">4896</span><span id="line-4896"> this.region = initHRegion(tableName, method, CONF, family);</span>
<span class="source-line-no">4897</span><span id="line-4897"> Put put = new Put(Bytes.toBytes(1L));</span>
<span class="source-line-no">4898</span><span id="line-4898"> put.addColumn(family, qual1, 1L, Bytes.toBytes(1L));</span>
<span class="source-line-no">4899</span><span id="line-4899"> region.put(put);</span>
<span class="source-line-no">4900</span><span id="line-4900"></span>
<span class="source-line-no">4901</span><span id="line-4901"> region.flush(true);</span>
<span class="source-line-no">4902</span><span id="line-4902"></span>
<span class="source-line-no">4903</span><span id="line-4903"> Delete delete = new Delete(Bytes.toBytes(1L), 1L);</span>
<span class="source-line-no">4904</span><span id="line-4904"> region.delete(delete);</span>
<span class="source-line-no">4905</span><span id="line-4905"></span>
<span class="source-line-no">4906</span><span id="line-4906"> put = new Put(Bytes.toBytes(2L));</span>
<span class="source-line-no">4907</span><span id="line-4907"> put.addColumn(family, qual1, 2L, Bytes.toBytes(2L));</span>
<span class="source-line-no">4908</span><span id="line-4908"> region.put(put);</span>
<span class="source-line-no">4909</span><span id="line-4909"></span>
<span class="source-line-no">4910</span><span id="line-4910"> Scan idxScan = new Scan();</span>
<span class="source-line-no">4911</span><span id="line-4911"> idxScan.addFamily(family);</span>
<span class="source-line-no">4912</span><span id="line-4912"> idxScan.setFilter(new FilterList(FilterList.Operator.MUST_PASS_ALL,</span>
<span class="source-line-no">4913</span><span id="line-4913"> Arrays.&lt;Filter&gt; asList(</span>
<span class="source-line-no">4914</span><span id="line-4914"> new SingleColumnValueFilter(family, qual1, CompareOperator.GREATER_OR_EQUAL,</span>
<span class="source-line-no">4915</span><span id="line-4915"> new BinaryComparator(Bytes.toBytes(0L))),</span>
<span class="source-line-no">4916</span><span id="line-4916"> new SingleColumnValueFilter(family, qual1, CompareOperator.LESS_OR_EQUAL,</span>
<span class="source-line-no">4917</span><span id="line-4917"> new BinaryComparator(Bytes.toBytes(3L))))));</span>
<span class="source-line-no">4918</span><span id="line-4918"> try (InternalScanner scanner = region.getScanner(idxScan)) {</span>
<span class="source-line-no">4919</span><span id="line-4919"> List&lt;Cell&gt; res = new ArrayList&lt;&gt;();</span>
<span class="source-line-no">4920</span><span id="line-4920"></span>
<span class="source-line-no">4921</span><span id="line-4921"> while (scanner.next(res)) {</span>
<span class="source-line-no">4922</span><span id="line-4922"> // Ignore res value.</span>
<span class="source-line-no">4923</span><span id="line-4923"> }</span>
<span class="source-line-no">4924</span><span id="line-4924"> assertEquals(1L, res.size());</span>
<span class="source-line-no">4925</span><span id="line-4925"> }</span>
<span class="source-line-no">4926</span><span id="line-4926"> }</span>
<span class="source-line-no">4927</span><span id="line-4927"></span>
<span class="source-line-no">4928</span><span id="line-4928"> // ////////////////////////////////////////////////////////////////////////////</span>
<span class="source-line-no">4929</span><span id="line-4929"> // Bloom filter test</span>
<span class="source-line-no">4930</span><span id="line-4930"> // ////////////////////////////////////////////////////////////////////////////</span>
<span class="source-line-no">4931</span><span id="line-4931"> @Test</span>
<span class="source-line-no">4932</span><span id="line-4932"> public void testBloomFilterSize() throws IOException {</span>
<span class="source-line-no">4933</span><span id="line-4933"> byte[] fam1 = Bytes.toBytes("fam1");</span>
<span class="source-line-no">4934</span><span id="line-4934"> byte[] qf1 = Bytes.toBytes("col");</span>
<span class="source-line-no">4935</span><span id="line-4935"> byte[] val1 = Bytes.toBytes("value1");</span>
<span class="source-line-no">4936</span><span id="line-4936"> // Create Table</span>
<span class="source-line-no">4937</span><span id="line-4937"> TableDescriptor tableDescriptor = TableDescriptorBuilder.newBuilder(tableName)</span>
<span class="source-line-no">4938</span><span id="line-4938"> .setColumnFamily(ColumnFamilyDescriptorBuilder.newBuilder(fam1)</span>
<span class="source-line-no">4939</span><span id="line-4939"> .setMaxVersions(Integer.MAX_VALUE).setBloomFilterType(BloomType.ROWCOL).build())</span>
<span class="source-line-no">4940</span><span id="line-4940"> .build();</span>
<span class="source-line-no">4941</span><span id="line-4941"> RegionInfo info = RegionInfoBuilder.newBuilder(tableDescriptor.getTableName()).build();</span>
<span class="source-line-no">4942</span><span id="line-4942"> this.region = TEST_UTIL.createLocalHRegion(info, tableDescriptor);</span>
<span class="source-line-no">4943</span><span id="line-4943"> int num_unique_rows = 10;</span>
<span class="source-line-no">4944</span><span id="line-4944"> int duplicate_multiplier = 2;</span>
<span class="source-line-no">4945</span><span id="line-4945"> int num_storefiles = 4;</span>
<span class="source-line-no">4946</span><span id="line-4946"></span>
<span class="source-line-no">4947</span><span id="line-4947"> int version = 0;</span>
<span class="source-line-no">4948</span><span id="line-4948"> for (int f = 0; f &lt; num_storefiles; f++) {</span>
<span class="source-line-no">4949</span><span id="line-4949"> for (int i = 0; i &lt; duplicate_multiplier; i++) {</span>
<span class="source-line-no">4950</span><span id="line-4950"> for (int j = 0; j &lt; num_unique_rows; j++) {</span>
<span class="source-line-no">4951</span><span id="line-4951"> Put put = new Put(Bytes.toBytes("row" + j));</span>
<span class="source-line-no">4952</span><span id="line-4952"> put.setDurability(Durability.SKIP_WAL);</span>
<span class="source-line-no">4953</span><span id="line-4953"> long ts = version++;</span>
<span class="source-line-no">4954</span><span id="line-4954"> put.addColumn(fam1, qf1, ts, val1);</span>
<span class="source-line-no">4955</span><span id="line-4955"> region.put(put);</span>
<span class="source-line-no">4956</span><span id="line-4956"> }</span>
<span class="source-line-no">4957</span><span id="line-4957"> }</span>
<span class="source-line-no">4958</span><span id="line-4958"> region.flush(true);</span>
<span class="source-line-no">4959</span><span id="line-4959"> }</span>
<span class="source-line-no">4960</span><span id="line-4960"> // before compaction</span>
<span class="source-line-no">4961</span><span id="line-4961"> HStore store = region.getStore(fam1);</span>
<span class="source-line-no">4962</span><span id="line-4962"> Collection&lt;HStoreFile&gt; storeFiles = store.getStorefiles();</span>
<span class="source-line-no">4963</span><span id="line-4963"> for (HStoreFile storefile : storeFiles) {</span>
<span class="source-line-no">4964</span><span id="line-4964"> StoreFileReader reader = storefile.getReader();</span>
<span class="source-line-no">4965</span><span id="line-4965"> reader.loadFileInfo();</span>
<span class="source-line-no">4966</span><span id="line-4966"> reader.loadBloomfilter();</span>
<span class="source-line-no">4967</span><span id="line-4967"> assertEquals(num_unique_rows * duplicate_multiplier, reader.getEntries());</span>
<span class="source-line-no">4968</span><span id="line-4968"> assertEquals(num_unique_rows, reader.getFilterEntries());</span>
<span class="source-line-no">4969</span><span id="line-4969"> }</span>
<span class="source-line-no">4970</span><span id="line-4970"></span>
<span class="source-line-no">4971</span><span id="line-4971"> region.compact(true);</span>
<span class="source-line-no">4972</span><span id="line-4972"></span>
<span class="source-line-no">4973</span><span id="line-4973"> // after compaction</span>
<span class="source-line-no">4974</span><span id="line-4974"> storeFiles = store.getStorefiles();</span>
<span class="source-line-no">4975</span><span id="line-4975"> for (HStoreFile storefile : storeFiles) {</span>
<span class="source-line-no">4976</span><span id="line-4976"> StoreFileReader reader = storefile.getReader();</span>
<span class="source-line-no">4977</span><span id="line-4977"> reader.loadFileInfo();</span>
<span class="source-line-no">4978</span><span id="line-4978"> reader.loadBloomfilter();</span>
<span class="source-line-no">4979</span><span id="line-4979"> assertEquals(num_unique_rows * duplicate_multiplier * num_storefiles, reader.getEntries());</span>
<span class="source-line-no">4980</span><span id="line-4980"> assertEquals(num_unique_rows, reader.getFilterEntries());</span>
<span class="source-line-no">4981</span><span id="line-4981"> }</span>
<span class="source-line-no">4982</span><span id="line-4982"> }</span>
<span class="source-line-no">4983</span><span id="line-4983"></span>
<span class="source-line-no">4984</span><span id="line-4984"> @Test</span>
<span class="source-line-no">4985</span><span id="line-4985"> public void testAllColumnsWithBloomFilter() throws IOException {</span>
<span class="source-line-no">4986</span><span id="line-4986"> byte[] TABLE = Bytes.toBytes(name.getMethodName());</span>
<span class="source-line-no">4987</span><span id="line-4987"> byte[] FAMILY = Bytes.toBytes("family");</span>
<span class="source-line-no">4988</span><span id="line-4988"></span>
<span class="source-line-no">4989</span><span id="line-4989"> // Create table</span>
<span class="source-line-no">4990</span><span id="line-4990"> TableDescriptor tableDescriptor = TableDescriptorBuilder.newBuilder(TableName.valueOf(TABLE))</span>
<span class="source-line-no">4991</span><span id="line-4991"> .setColumnFamily(ColumnFamilyDescriptorBuilder.newBuilder(FAMILY)</span>
<span class="source-line-no">4992</span><span id="line-4992"> .setMaxVersions(Integer.MAX_VALUE).setBloomFilterType(BloomType.ROWCOL).build())</span>
<span class="source-line-no">4993</span><span id="line-4993"> .build();</span>
<span class="source-line-no">4994</span><span id="line-4994"> RegionInfo info = RegionInfoBuilder.newBuilder(tableDescriptor.getTableName()).build();</span>
<span class="source-line-no">4995</span><span id="line-4995"> this.region = TEST_UTIL.createLocalHRegion(info, tableDescriptor);</span>
<span class="source-line-no">4996</span><span id="line-4996"> // For row:0, col:0: insert versions 1 through 5.</span>
<span class="source-line-no">4997</span><span id="line-4997"> byte[] row = Bytes.toBytes("row:" + 0);</span>
<span class="source-line-no">4998</span><span id="line-4998"> byte[] column = Bytes.toBytes("column:" + 0);</span>
<span class="source-line-no">4999</span><span id="line-4999"> Put put = new Put(row);</span>
<span class="source-line-no">5000</span><span id="line-5000"> put.setDurability(Durability.SKIP_WAL);</span>
<span class="source-line-no">5001</span><span id="line-5001"> for (long idx = 1; idx &lt;= 4; idx++) {</span>
<span class="source-line-no">5002</span><span id="line-5002"> put.addColumn(FAMILY, column, idx, Bytes.toBytes("value-version-" + idx));</span>
<span class="source-line-no">5003</span><span id="line-5003"> }</span>
<span class="source-line-no">5004</span><span id="line-5004"> region.put(put);</span>
<span class="source-line-no">5005</span><span id="line-5005"></span>
<span class="source-line-no">5006</span><span id="line-5006"> // Flush</span>
<span class="source-line-no">5007</span><span id="line-5007"> region.flush(true);</span>
<span class="source-line-no">5008</span><span id="line-5008"></span>
<span class="source-line-no">5009</span><span id="line-5009"> // Get rows</span>
<span class="source-line-no">5010</span><span id="line-5010"> Get get = new Get(row);</span>
<span class="source-line-no">5011</span><span id="line-5011"> get.readAllVersions();</span>
<span class="source-line-no">5012</span><span id="line-5012"> Cell[] kvs = region.get(get).rawCells();</span>
<span class="source-line-no">5013</span><span id="line-5013"></span>
<span class="source-line-no">5014</span><span id="line-5014"> // Check if rows are correct</span>
<span class="source-line-no">5015</span><span id="line-5015"> assertEquals(4, kvs.length);</span>
<span class="source-line-no">5016</span><span id="line-5016"> checkOneCell(kvs[0], FAMILY, 0, 0, 4);</span>
<span class="source-line-no">5017</span><span id="line-5017"> checkOneCell(kvs[1], FAMILY, 0, 0, 3);</span>
<span class="source-line-no">5018</span><span id="line-5018"> checkOneCell(kvs[2], FAMILY, 0, 0, 2);</span>
<span class="source-line-no">5019</span><span id="line-5019"> checkOneCell(kvs[3], FAMILY, 0, 0, 1);</span>
<span class="source-line-no">5020</span><span id="line-5020"> }</span>
<span class="source-line-no">5021</span><span id="line-5021"></span>
<span class="source-line-no">5022</span><span id="line-5022"> /**</span>
<span class="source-line-no">5023</span><span id="line-5023"> * Testcase to cover bug-fix for HBASE-2823 Ensures correct delete when issuing delete row on</span>
<span class="source-line-no">5024</span><span id="line-5024"> * columns with bloom filter set to row+col (BloomType.ROWCOL)</span>
<span class="source-line-no">5025</span><span id="line-5025"> */</span>
<span class="source-line-no">5026</span><span id="line-5026"> @Test</span>
<span class="source-line-no">5027</span><span id="line-5027"> public void testDeleteRowWithBloomFilter() throws IOException {</span>
<span class="source-line-no">5028</span><span id="line-5028"> byte[] familyName = Bytes.toBytes("familyName");</span>
<span class="source-line-no">5029</span><span id="line-5029"></span>
<span class="source-line-no">5030</span><span id="line-5030"> // Create Table</span>
<span class="source-line-no">5031</span><span id="line-5031"> TableDescriptor tableDescriptor = TableDescriptorBuilder.newBuilder(tableName)</span>
<span class="source-line-no">5032</span><span id="line-5032"> .setColumnFamily(ColumnFamilyDescriptorBuilder.newBuilder(familyName)</span>
<span class="source-line-no">5033</span><span id="line-5033"> .setMaxVersions(Integer.MAX_VALUE).setBloomFilterType(BloomType.ROWCOL).build())</span>
<span class="source-line-no">5034</span><span id="line-5034"> .build();</span>
<span class="source-line-no">5035</span><span id="line-5035"> RegionInfo info = RegionInfoBuilder.newBuilder(tableDescriptor.getTableName()).build();</span>
<span class="source-line-no">5036</span><span id="line-5036"> this.region = TEST_UTIL.createLocalHRegion(info, tableDescriptor);</span>
<span class="source-line-no">5037</span><span id="line-5037"> // Insert some data</span>
<span class="source-line-no">5038</span><span id="line-5038"> byte[] row = Bytes.toBytes("row1");</span>
<span class="source-line-no">5039</span><span id="line-5039"> byte[] col = Bytes.toBytes("col1");</span>
<span class="source-line-no">5040</span><span id="line-5040"></span>
<span class="source-line-no">5041</span><span id="line-5041"> Put put = new Put(row);</span>
<span class="source-line-no">5042</span><span id="line-5042"> put.addColumn(familyName, col, 1, Bytes.toBytes("SomeRandomValue"));</span>
<span class="source-line-no">5043</span><span id="line-5043"> region.put(put);</span>
<span class="source-line-no">5044</span><span id="line-5044"> region.flush(true);</span>
<span class="source-line-no">5045</span><span id="line-5045"></span>
<span class="source-line-no">5046</span><span id="line-5046"> Delete del = new Delete(row);</span>
<span class="source-line-no">5047</span><span id="line-5047"> region.delete(del);</span>
<span class="source-line-no">5048</span><span id="line-5048"> region.flush(true);</span>
<span class="source-line-no">5049</span><span id="line-5049"></span>
<span class="source-line-no">5050</span><span id="line-5050"> // Get remaining rows (should have none)</span>
<span class="source-line-no">5051</span><span id="line-5051"> Get get = new Get(row);</span>
<span class="source-line-no">5052</span><span id="line-5052"> get.addColumn(familyName, col);</span>
<span class="source-line-no">5053</span><span id="line-5053"></span>
<span class="source-line-no">5054</span><span id="line-5054"> Cell[] keyValues = region.get(get).rawCells();</span>
<span class="source-line-no">5055</span><span id="line-5055"> assertEquals(0, keyValues.length);</span>
<span class="source-line-no">5056</span><span id="line-5056"> }</span>
<span class="source-line-no">5057</span><span id="line-5057"></span>
<span class="source-line-no">5058</span><span id="line-5058"> @Test</span>
<span class="source-line-no">5059</span><span id="line-5059"> public void testgetHDFSBlocksDistribution() throws Exception {</span>
<span class="source-line-no">5060</span><span id="line-5060"> HBaseTestingUtil htu = new HBaseTestingUtil();</span>
<span class="source-line-no">5061</span><span id="line-5061"> // Why do we set the block size in this test? If we set it smaller than the kvs, then we'll</span>
<span class="source-line-no">5062</span><span id="line-5062"> // break up the file in to more pieces that can be distributed across the three nodes and we</span>
<span class="source-line-no">5063</span><span id="line-5063"> // won't be able to have the condition this test asserts; that at least one node has</span>
<span class="source-line-no">5064</span><span id="line-5064"> // a copy of all replicas -- if small block size, then blocks are spread evenly across the</span>
<span class="source-line-no">5065</span><span id="line-5065"> // the three nodes. hfilev3 with tags seems to put us over the block size. St.Ack.</span>
<span class="source-line-no">5066</span><span id="line-5066"> // final int DEFAULT_BLOCK_SIZE = 1024;</span>
<span class="source-line-no">5067</span><span id="line-5067"> // htu.getConfiguration().setLong("dfs.blocksize", DEFAULT_BLOCK_SIZE);</span>
<span class="source-line-no">5068</span><span id="line-5068"> htu.getConfiguration().setInt("dfs.replication", 2);</span>
<span class="source-line-no">5069</span><span id="line-5069"></span>
<span class="source-line-no">5070</span><span id="line-5070"> // set up a cluster with 3 nodes</span>
<span class="source-line-no">5071</span><span id="line-5071"> SingleProcessHBaseCluster cluster = null;</span>
<span class="source-line-no">5072</span><span id="line-5072"> String dataNodeHosts[] = new String[] { "host1", "host2", "host3" };</span>
<span class="source-line-no">5073</span><span id="line-5073"> int regionServersCount = 3;</span>
<span class="source-line-no">5074</span><span id="line-5074"></span>
<span class="source-line-no">5075</span><span id="line-5075"> try {</span>
<span class="source-line-no">5076</span><span id="line-5076"> StartTestingClusterOption option = StartTestingClusterOption.builder()</span>
<span class="source-line-no">5077</span><span id="line-5077"> .numRegionServers(regionServersCount).dataNodeHosts(dataNodeHosts).build();</span>
<span class="source-line-no">5078</span><span id="line-5078"> cluster = htu.startMiniCluster(option);</span>
<span class="source-line-no">5079</span><span id="line-5079"> byte[][] families = { fam1, fam2 };</span>
<span class="source-line-no">5080</span><span id="line-5080"> Table ht = htu.createTable(tableName, families);</span>
<span class="source-line-no">5081</span><span id="line-5081"></span>
<span class="source-line-no">5082</span><span id="line-5082"> // Setting up region</span>
<span class="source-line-no">5083</span><span id="line-5083"> byte row[] = Bytes.toBytes("row1");</span>
<span class="source-line-no">5084</span><span id="line-5084"> byte col[] = Bytes.toBytes("col1");</span>
<span class="source-line-no">5085</span><span id="line-5085"></span>
<span class="source-line-no">5086</span><span id="line-5086"> Put put = new Put(row);</span>
<span class="source-line-no">5087</span><span id="line-5087"> put.addColumn(fam1, col, 1, Bytes.toBytes("test1"));</span>
<span class="source-line-no">5088</span><span id="line-5088"> put.addColumn(fam2, col, 1, Bytes.toBytes("test2"));</span>
<span class="source-line-no">5089</span><span id="line-5089"> ht.put(put);</span>
<span class="source-line-no">5090</span><span id="line-5090"></span>
<span class="source-line-no">5091</span><span id="line-5091"> HRegion firstRegion = htu.getHBaseCluster().getRegions(tableName).get(0);</span>
<span class="source-line-no">5092</span><span id="line-5092"> firstRegion.flush(true);</span>
<span class="source-line-no">5093</span><span id="line-5093"> HDFSBlocksDistribution blocksDistribution1 = firstRegion.getHDFSBlocksDistribution();</span>
<span class="source-line-no">5094</span><span id="line-5094"></span>
<span class="source-line-no">5095</span><span id="line-5095"> // Given the default replication factor is 2 and we have 2 HFiles,</span>
<span class="source-line-no">5096</span><span id="line-5096"> // we will have total of 4 replica of blocks on 3 datanodes; thus there</span>
<span class="source-line-no">5097</span><span id="line-5097"> // must be at least one host that have replica for 2 HFiles. That host's</span>
<span class="source-line-no">5098</span><span id="line-5098"> // weight will be equal to the unique block weight.</span>
<span class="source-line-no">5099</span><span id="line-5099"> long uniqueBlocksWeight1 = blocksDistribution1.getUniqueBlocksTotalWeight();</span>
<span class="source-line-no">5100</span><span id="line-5100"> StringBuilder sb = new StringBuilder();</span>
<span class="source-line-no">5101</span><span id="line-5101"> for (String host : blocksDistribution1.getTopHosts()) {</span>
<span class="source-line-no">5102</span><span id="line-5102"> if (sb.length() &gt; 0) sb.append(", ");</span>
<span class="source-line-no">5103</span><span id="line-5103"> sb.append(host);</span>
<span class="source-line-no">5104</span><span id="line-5104"> sb.append("=");</span>
<span class="source-line-no">5105</span><span id="line-5105"> sb.append(blocksDistribution1.getWeight(host));</span>
<span class="source-line-no">5106</span><span id="line-5106"> }</span>
<span class="source-line-no">5107</span><span id="line-5107"></span>
<span class="source-line-no">5108</span><span id="line-5108"> String topHost = blocksDistribution1.getTopHosts().get(0);</span>
<span class="source-line-no">5109</span><span id="line-5109"> long topHostWeight = blocksDistribution1.getWeight(topHost);</span>
<span class="source-line-no">5110</span><span id="line-5110"> String msg = "uniqueBlocksWeight=" + uniqueBlocksWeight1 + ", topHostWeight=" + topHostWeight</span>
<span class="source-line-no">5111</span><span id="line-5111"> + ", topHost=" + topHost + "; " + sb.toString();</span>
<span class="source-line-no">5112</span><span id="line-5112"> LOG.info(msg);</span>
<span class="source-line-no">5113</span><span id="line-5113"> assertTrue(msg, uniqueBlocksWeight1 == topHostWeight);</span>
<span class="source-line-no">5114</span><span id="line-5114"></span>
<span class="source-line-no">5115</span><span id="line-5115"> // use the static method to compute the value, it should be the same.</span>
<span class="source-line-no">5116</span><span id="line-5116"> // static method is used by load balancer or other components</span>
<span class="source-line-no">5117</span><span id="line-5117"> HDFSBlocksDistribution blocksDistribution2 = HRegion.computeHDFSBlocksDistribution(</span>
<span class="source-line-no">5118</span><span id="line-5118"> htu.getConfiguration(), firstRegion.getTableDescriptor(), firstRegion.getRegionInfo());</span>
<span class="source-line-no">5119</span><span id="line-5119"> long uniqueBlocksWeight2 = blocksDistribution2.getUniqueBlocksTotalWeight();</span>
<span class="source-line-no">5120</span><span id="line-5120"></span>
<span class="source-line-no">5121</span><span id="line-5121"> assertTrue(uniqueBlocksWeight1 == uniqueBlocksWeight2);</span>
<span class="source-line-no">5122</span><span id="line-5122"></span>
<span class="source-line-no">5123</span><span id="line-5123"> ht.close();</span>
<span class="source-line-no">5124</span><span id="line-5124"> } finally {</span>
<span class="source-line-no">5125</span><span id="line-5125"> if (cluster != null) {</span>
<span class="source-line-no">5126</span><span id="line-5126"> htu.shutdownMiniCluster();</span>
<span class="source-line-no">5127</span><span id="line-5127"> }</span>
<span class="source-line-no">5128</span><span id="line-5128"> }</span>
<span class="source-line-no">5129</span><span id="line-5129"> }</span>
<span class="source-line-no">5130</span><span id="line-5130"></span>
<span class="source-line-no">5131</span><span id="line-5131"> /**</span>
<span class="source-line-no">5132</span><span id="line-5132"> * Testcase to check state of region initialization task set to ABORTED or not if any exceptions</span>
<span class="source-line-no">5133</span><span id="line-5133"> * during initialization</span>
<span class="source-line-no">5134</span><span id="line-5134"> */</span>
<span class="source-line-no">5135</span><span id="line-5135"> @Test</span>
<span class="source-line-no">5136</span><span id="line-5136"> public void testStatusSettingToAbortIfAnyExceptionDuringRegionInitilization() throws Exception {</span>
<span class="source-line-no">5137</span><span id="line-5137"> RegionInfo info;</span>
<span class="source-line-no">5138</span><span id="line-5138"> try {</span>
<span class="source-line-no">5139</span><span id="line-5139"> FileSystem fs = mock(FileSystem.class);</span>
<span class="source-line-no">5140</span><span id="line-5140"> when(fs.exists(any())).thenThrow(new IOException());</span>
<span class="source-line-no">5141</span><span id="line-5141"> TableDescriptorBuilder tableDescriptorBuilder = TableDescriptorBuilder.newBuilder(tableName);</span>
<span class="source-line-no">5142</span><span id="line-5142"> ColumnFamilyDescriptor columnFamilyDescriptor =</span>
<span class="source-line-no">5143</span><span id="line-5143"> ColumnFamilyDescriptorBuilder.newBuilder(Bytes.toBytes("cf")).build();</span>
<span class="source-line-no">5144</span><span id="line-5144"> tableDescriptorBuilder.setColumnFamily(columnFamilyDescriptor);</span>
<span class="source-line-no">5145</span><span id="line-5145"> info = RegionInfoBuilder.newBuilder(tableName).build();</span>
<span class="source-line-no">5146</span><span id="line-5146"> Path path = new Path(dir + "testStatusSettingToAbortIfAnyExceptionDuringRegionInitilization");</span>
<span class="source-line-no">5147</span><span id="line-5147"> region = HRegion.newHRegion(path, null, fs, CONF, info, tableDescriptorBuilder.build(), null);</span>
<span class="source-line-no">5148</span><span id="line-5148"> // region initialization throws IOException and set task state to ABORTED.</span>
<span class="source-line-no">5149</span><span id="line-5149"> region.initialize();</span>
<span class="source-line-no">5150</span><span id="line-5150"> fail("Region initialization should fail due to IOException");</span>
<span class="source-line-no">5151</span><span id="line-5151"> } catch (IOException io) {</span>
<span class="source-line-no">5152</span><span id="line-5152"> List&lt;MonitoredTask&gt; tasks = TaskMonitor.get().getTasks();</span>
<span class="source-line-no">5153</span><span id="line-5153"> for (MonitoredTask monitoredTask : tasks) {</span>
<span class="source-line-no">5154</span><span id="line-5154"> if (</span>
<span class="source-line-no">5155</span><span id="line-5155"> !(monitoredTask instanceof MonitoredRPCHandler)</span>
<span class="source-line-no">5156</span><span id="line-5156"> &amp;&amp; monitoredTask.getDescription().contains(region.toString())</span>
<span class="source-line-no">5157</span><span id="line-5157"> ) {</span>
<span class="source-line-no">5158</span><span id="line-5158"> assertTrue("Region state should be ABORTED.",</span>
<span class="source-line-no">5159</span><span id="line-5159"> monitoredTask.getState().equals(MonitoredTask.State.ABORTED));</span>
<span class="source-line-no">5160</span><span id="line-5160"> break;</span>
<span class="source-line-no">5161</span><span id="line-5161"> }</span>
<span class="source-line-no">5162</span><span id="line-5162"> }</span>
<span class="source-line-no">5163</span><span id="line-5163"> }</span>
<span class="source-line-no">5164</span><span id="line-5164"> }</span>
<span class="source-line-no">5165</span><span id="line-5165"></span>
<span class="source-line-no">5166</span><span id="line-5166"> /**</span>
<span class="source-line-no">5167</span><span id="line-5167"> * Verifies that the .regioninfo file is written on region creation and that is recreated if</span>
<span class="source-line-no">5168</span><span id="line-5168"> * missing during region opening.</span>
<span class="source-line-no">5169</span><span id="line-5169"> */</span>
<span class="source-line-no">5170</span><span id="line-5170"> @Test</span>
<span class="source-line-no">5171</span><span id="line-5171"> public void testRegionInfoFileCreation() throws IOException {</span>
<span class="source-line-no">5172</span><span id="line-5172"> Path rootDir = new Path(dir + "testRegionInfoFileCreation");</span>
<span class="source-line-no">5173</span><span id="line-5173"></span>
<span class="source-line-no">5174</span><span id="line-5174"> TableDescriptorBuilder tableDescriptorBuilder =</span>
<span class="source-line-no">5175</span><span id="line-5175"> TableDescriptorBuilder.newBuilder(TableName.valueOf(name.getMethodName()));</span>
<span class="source-line-no">5176</span><span id="line-5176"> ColumnFamilyDescriptor columnFamilyDescriptor =</span>
<span class="source-line-no">5177</span><span id="line-5177"> ColumnFamilyDescriptorBuilder.newBuilder(Bytes.toBytes("cf")).build();</span>
<span class="source-line-no">5178</span><span id="line-5178"> tableDescriptorBuilder.setColumnFamily(columnFamilyDescriptor);</span>
<span class="source-line-no">5179</span><span id="line-5179"> TableDescriptor tableDescriptor = tableDescriptorBuilder.build();</span>
<span class="source-line-no">5180</span><span id="line-5180"></span>
<span class="source-line-no">5181</span><span id="line-5181"> RegionInfo hri = RegionInfoBuilder.newBuilder(tableDescriptor.getTableName()).build();</span>
<span class="source-line-no">5182</span><span id="line-5182"></span>
<span class="source-line-no">5183</span><span id="line-5183"> // Create a region and skip the initialization (like CreateTableHandler)</span>
<span class="source-line-no">5184</span><span id="line-5184"> region = HBaseTestingUtil.createRegionAndWAL(hri, rootDir, CONF, tableDescriptor, false);</span>
<span class="source-line-no">5185</span><span id="line-5185"> Path regionDir = region.getRegionFileSystem().getRegionDir();</span>
<span class="source-line-no">5186</span><span id="line-5186"> FileSystem fs = region.getRegionFileSystem().getFileSystem();</span>
<span class="source-line-no">5187</span><span id="line-5187"> HBaseTestingUtil.closeRegionAndWAL(region);</span>
<span class="source-line-no">5188</span><span id="line-5188"></span>
<span class="source-line-no">5189</span><span id="line-5189"> Path regionInfoFile = new Path(regionDir, HRegionFileSystem.REGION_INFO_FILE);</span>
<span class="source-line-no">5190</span><span id="line-5190"></span>
<span class="source-line-no">5191</span><span id="line-5191"> // Verify that the .regioninfo file is present</span>
<span class="source-line-no">5192</span><span id="line-5192"> assertTrue(HRegionFileSystem.REGION_INFO_FILE + " should be present in the region dir",</span>
<span class="source-line-no">5193</span><span id="line-5193"> fs.exists(regionInfoFile));</span>
<span class="source-line-no">5194</span><span id="line-5194"></span>
<span class="source-line-no">5195</span><span id="line-5195"> // Try to open the region</span>
<span class="source-line-no">5196</span><span id="line-5196"> region = HRegion.openHRegion(rootDir, hri, tableDescriptor, null, CONF);</span>
<span class="source-line-no">5197</span><span id="line-5197"> assertEquals(regionDir, region.getRegionFileSystem().getRegionDir());</span>
<span class="source-line-no">5198</span><span id="line-5198"> HBaseTestingUtil.closeRegionAndWAL(region);</span>
<span class="source-line-no">5199</span><span id="line-5199"></span>
<span class="source-line-no">5200</span><span id="line-5200"> // Verify that the .regioninfo file is still there</span>
<span class="source-line-no">5201</span><span id="line-5201"> assertTrue(HRegionFileSystem.REGION_INFO_FILE + " should be present in the region dir",</span>
<span class="source-line-no">5202</span><span id="line-5202"> fs.exists(regionInfoFile));</span>
<span class="source-line-no">5203</span><span id="line-5203"></span>
<span class="source-line-no">5204</span><span id="line-5204"> // Remove the .regioninfo file and verify is recreated on region open</span>
<span class="source-line-no">5205</span><span id="line-5205"> fs.delete(regionInfoFile, true);</span>
<span class="source-line-no">5206</span><span id="line-5206"> assertFalse(HRegionFileSystem.REGION_INFO_FILE + " should be removed from the region dir",</span>
<span class="source-line-no">5207</span><span id="line-5207"> fs.exists(regionInfoFile));</span>
<span class="source-line-no">5208</span><span id="line-5208"></span>
<span class="source-line-no">5209</span><span id="line-5209"> region = HRegion.openHRegion(rootDir, hri, tableDescriptor, null, CONF);</span>
<span class="source-line-no">5210</span><span id="line-5210"> // region = TEST_UTIL.openHRegion(hri, htd);</span>
<span class="source-line-no">5211</span><span id="line-5211"> assertEquals(regionDir, region.getRegionFileSystem().getRegionDir());</span>
<span class="source-line-no">5212</span><span id="line-5212"> HBaseTestingUtil.closeRegionAndWAL(region);</span>
<span class="source-line-no">5213</span><span id="line-5213"></span>
<span class="source-line-no">5214</span><span id="line-5214"> // Verify that the .regioninfo file is still there</span>
<span class="source-line-no">5215</span><span id="line-5215"> assertTrue(HRegionFileSystem.REGION_INFO_FILE + " should be present in the region dir",</span>
<span class="source-line-no">5216</span><span id="line-5216"> fs.exists(new Path(regionDir, HRegionFileSystem.REGION_INFO_FILE)));</span>
<span class="source-line-no">5217</span><span id="line-5217"></span>
<span class="source-line-no">5218</span><span id="line-5218"> region = null;</span>
<span class="source-line-no">5219</span><span id="line-5219"> }</span>
<span class="source-line-no">5220</span><span id="line-5220"></span>
<span class="source-line-no">5221</span><span id="line-5221"> /**</span>
<span class="source-line-no">5222</span><span id="line-5222"> * TestCase for increment</span>
<span class="source-line-no">5223</span><span id="line-5223"> */</span>
<span class="source-line-no">5224</span><span id="line-5224"> private static class Incrementer implements Runnable {</span>
<span class="source-line-no">5225</span><span id="line-5225"> private HRegion region;</span>
<span class="source-line-no">5226</span><span id="line-5226"> private final static byte[] incRow = Bytes.toBytes("incRow");</span>
<span class="source-line-no">5227</span><span id="line-5227"> private final static byte[] family = Bytes.toBytes("family");</span>
<span class="source-line-no">5228</span><span id="line-5228"> private final static byte[] qualifier = Bytes.toBytes("qualifier");</span>
<span class="source-line-no">5229</span><span id="line-5229"> private final static long ONE = 1L;</span>
<span class="source-line-no">5230</span><span id="line-5230"> private int incCounter;</span>
<span class="source-line-no">5231</span><span id="line-5231"></span>
<span class="source-line-no">5232</span><span id="line-5232"> public Incrementer(HRegion region, int incCounter) {</span>
<span class="source-line-no">5233</span><span id="line-5233"> this.region = region;</span>
<span class="source-line-no">5234</span><span id="line-5234"> this.incCounter = incCounter;</span>
<span class="source-line-no">5235</span><span id="line-5235"> }</span>
<span class="source-line-no">5236</span><span id="line-5236"></span>
<span class="source-line-no">5237</span><span id="line-5237"> @Override</span>
<span class="source-line-no">5238</span><span id="line-5238"> public void run() {</span>
<span class="source-line-no">5239</span><span id="line-5239"> int count = 0;</span>
<span class="source-line-no">5240</span><span id="line-5240"> while (count &lt; incCounter) {</span>
<span class="source-line-no">5241</span><span id="line-5241"> Increment inc = new Increment(incRow);</span>
<span class="source-line-no">5242</span><span id="line-5242"> inc.addColumn(family, qualifier, ONE);</span>
<span class="source-line-no">5243</span><span id="line-5243"> count++;</span>
<span class="source-line-no">5244</span><span id="line-5244"> try {</span>
<span class="source-line-no">5245</span><span id="line-5245"> region.increment(inc);</span>
<span class="source-line-no">5246</span><span id="line-5246"> } catch (IOException e) {</span>
<span class="source-line-no">5247</span><span id="line-5247"> LOG.info("Count=" + count + ", " + e);</span>
<span class="source-line-no">5248</span><span id="line-5248"> break;</span>
<span class="source-line-no">5249</span><span id="line-5249"> }</span>
<span class="source-line-no">5250</span><span id="line-5250"> }</span>
<span class="source-line-no">5251</span><span id="line-5251"> }</span>
<span class="source-line-no">5252</span><span id="line-5252"> }</span>
<span class="source-line-no">5253</span><span id="line-5253"></span>
<span class="source-line-no">5254</span><span id="line-5254"> /**</span>
<span class="source-line-no">5255</span><span id="line-5255"> * Test case to check increment function with memstore flushing</span>
<span class="source-line-no">5256</span><span id="line-5256"> */</span>
<span class="source-line-no">5257</span><span id="line-5257"> @Test</span>
<span class="source-line-no">5258</span><span id="line-5258"> public void testParallelIncrementWithMemStoreFlush() throws Exception {</span>
<span class="source-line-no">5259</span><span id="line-5259"> byte[] family = Incrementer.family;</span>
<span class="source-line-no">5260</span><span id="line-5260"> this.region = initHRegion(tableName, method, CONF, family);</span>
<span class="source-line-no">5261</span><span id="line-5261"> final HRegion region = this.region;</span>
<span class="source-line-no">5262</span><span id="line-5262"> final AtomicBoolean incrementDone = new AtomicBoolean(false);</span>
<span class="source-line-no">5263</span><span id="line-5263"> Runnable flusher = new Runnable() {</span>
<span class="source-line-no">5264</span><span id="line-5264"> @Override</span>
<span class="source-line-no">5265</span><span id="line-5265"> public void run() {</span>
<span class="source-line-no">5266</span><span id="line-5266"> while (!incrementDone.get()) {</span>
<span class="source-line-no">5267</span><span id="line-5267"> try {</span>
<span class="source-line-no">5268</span><span id="line-5268"> region.flush(true);</span>
<span class="source-line-no">5269</span><span id="line-5269"> } catch (Exception e) {</span>
<span class="source-line-no">5270</span><span id="line-5270"> e.printStackTrace();</span>
<span class="source-line-no">5271</span><span id="line-5271"> }</span>
<span class="source-line-no">5272</span><span id="line-5272"> }</span>
<span class="source-line-no">5273</span><span id="line-5273"> }</span>
<span class="source-line-no">5274</span><span id="line-5274"> };</span>
<span class="source-line-no">5275</span><span id="line-5275"></span>
<span class="source-line-no">5276</span><span id="line-5276"> // after all increment finished, the row will increment to 20*100 = 2000</span>
<span class="source-line-no">5277</span><span id="line-5277"> int threadNum = 20;</span>
<span class="source-line-no">5278</span><span id="line-5278"> int incCounter = 100;</span>
<span class="source-line-no">5279</span><span id="line-5279"> long expected = (long) threadNum * incCounter;</span>
<span class="source-line-no">5280</span><span id="line-5280"> Thread[] incrementers = new Thread[threadNum];</span>
<span class="source-line-no">5281</span><span id="line-5281"> Thread flushThread = new Thread(flusher);</span>
<span class="source-line-no">5282</span><span id="line-5282"> for (int i = 0; i &lt; threadNum; i++) {</span>
<span class="source-line-no">5283</span><span id="line-5283"> incrementers[i] = new Thread(new Incrementer(this.region, incCounter));</span>
<span class="source-line-no">5284</span><span id="line-5284"> incrementers[i].start();</span>
<span class="source-line-no">5285</span><span id="line-5285"> }</span>
<span class="source-line-no">5286</span><span id="line-5286"> flushThread.start();</span>
<span class="source-line-no">5287</span><span id="line-5287"> for (int i = 0; i &lt; threadNum; i++) {</span>
<span class="source-line-no">5288</span><span id="line-5288"> incrementers[i].join();</span>
<span class="source-line-no">5289</span><span id="line-5289"> }</span>
<span class="source-line-no">5290</span><span id="line-5290"></span>
<span class="source-line-no">5291</span><span id="line-5291"> incrementDone.set(true);</span>
<span class="source-line-no">5292</span><span id="line-5292"> flushThread.join();</span>
<span class="source-line-no">5293</span><span id="line-5293"></span>
<span class="source-line-no">5294</span><span id="line-5294"> Get get = new Get(Incrementer.incRow);</span>
<span class="source-line-no">5295</span><span id="line-5295"> get.addColumn(Incrementer.family, Incrementer.qualifier);</span>
<span class="source-line-no">5296</span><span id="line-5296"> get.readVersions(1);</span>
<span class="source-line-no">5297</span><span id="line-5297"> Result res = this.region.get(get);</span>
<span class="source-line-no">5298</span><span id="line-5298"> List&lt;Cell&gt; kvs = res.getColumnCells(Incrementer.family, Incrementer.qualifier);</span>
<span class="source-line-no">5299</span><span id="line-5299"></span>
<span class="source-line-no">5300</span><span id="line-5300"> // we just got the latest version</span>
<span class="source-line-no">5301</span><span id="line-5301"> assertEquals(1, kvs.size());</span>
<span class="source-line-no">5302</span><span id="line-5302"> Cell kv = kvs.get(0);</span>
<span class="source-line-no">5303</span><span id="line-5303"> assertEquals(expected, Bytes.toLong(kv.getValueArray(), kv.getValueOffset()));</span>
<span class="source-line-no">5304</span><span id="line-5304"> }</span>
<span class="source-line-no">5305</span><span id="line-5305"></span>
<span class="source-line-no">5306</span><span id="line-5306"> /**</span>
<span class="source-line-no">5307</span><span id="line-5307"> * TestCase for append</span>
<span class="source-line-no">5308</span><span id="line-5308"> */</span>
<span class="source-line-no">5309</span><span id="line-5309"> private static class Appender implements Runnable {</span>
<span class="source-line-no">5310</span><span id="line-5310"> private HRegion region;</span>
<span class="source-line-no">5311</span><span id="line-5311"> private final static byte[] appendRow = Bytes.toBytes("appendRow");</span>
<span class="source-line-no">5312</span><span id="line-5312"> private final static byte[] family = Bytes.toBytes("family");</span>
<span class="source-line-no">5313</span><span id="line-5313"> private final static byte[] qualifier = Bytes.toBytes("qualifier");</span>
<span class="source-line-no">5314</span><span id="line-5314"> private final static byte[] CHAR = Bytes.toBytes("a");</span>
<span class="source-line-no">5315</span><span id="line-5315"> private int appendCounter;</span>
<span class="source-line-no">5316</span><span id="line-5316"></span>
<span class="source-line-no">5317</span><span id="line-5317"> public Appender(HRegion region, int appendCounter) {</span>
<span class="source-line-no">5318</span><span id="line-5318"> this.region = region;</span>
<span class="source-line-no">5319</span><span id="line-5319"> this.appendCounter = appendCounter;</span>
<span class="source-line-no">5320</span><span id="line-5320"> }</span>
<span class="source-line-no">5321</span><span id="line-5321"></span>
<span class="source-line-no">5322</span><span id="line-5322"> @Override</span>
<span class="source-line-no">5323</span><span id="line-5323"> public void run() {</span>
<span class="source-line-no">5324</span><span id="line-5324"> int count = 0;</span>
<span class="source-line-no">5325</span><span id="line-5325"> while (count &lt; appendCounter) {</span>
<span class="source-line-no">5326</span><span id="line-5326"> Append app = new Append(appendRow);</span>
<span class="source-line-no">5327</span><span id="line-5327"> app.addColumn(family, qualifier, CHAR);</span>
<span class="source-line-no">5328</span><span id="line-5328"> count++;</span>
<span class="source-line-no">5329</span><span id="line-5329"> try {</span>
<span class="source-line-no">5330</span><span id="line-5330"> region.append(app);</span>
<span class="source-line-no">5331</span><span id="line-5331"> } catch (IOException e) {</span>
<span class="source-line-no">5332</span><span id="line-5332"> LOG.info("Count=" + count + ", max=" + appendCounter + ", " + e);</span>
<span class="source-line-no">5333</span><span id="line-5333"> break;</span>
<span class="source-line-no">5334</span><span id="line-5334"> }</span>
<span class="source-line-no">5335</span><span id="line-5335"> }</span>
<span class="source-line-no">5336</span><span id="line-5336"> }</span>
<span class="source-line-no">5337</span><span id="line-5337"> }</span>
<span class="source-line-no">5338</span><span id="line-5338"></span>
<span class="source-line-no">5339</span><span id="line-5339"> /**</span>
<span class="source-line-no">5340</span><span id="line-5340"> * Test case to check append function with memstore flushing</span>
<span class="source-line-no">5341</span><span id="line-5341"> */</span>
<span class="source-line-no">5342</span><span id="line-5342"> @Test</span>
<span class="source-line-no">5343</span><span id="line-5343"> public void testParallelAppendWithMemStoreFlush() throws Exception {</span>
<span class="source-line-no">5344</span><span id="line-5344"> byte[] family = Appender.family;</span>
<span class="source-line-no">5345</span><span id="line-5345"> this.region = initHRegion(tableName, method, CONF, family);</span>
<span class="source-line-no">5346</span><span id="line-5346"> final HRegion region = this.region;</span>
<span class="source-line-no">5347</span><span id="line-5347"> final AtomicBoolean appendDone = new AtomicBoolean(false);</span>
<span class="source-line-no">5348</span><span id="line-5348"> Runnable flusher = new Runnable() {</span>
<span class="source-line-no">5349</span><span id="line-5349"> @Override</span>
<span class="source-line-no">5350</span><span id="line-5350"> public void run() {</span>
<span class="source-line-no">5351</span><span id="line-5351"> while (!appendDone.get()) {</span>
<span class="source-line-no">5352</span><span id="line-5352"> try {</span>
<span class="source-line-no">5353</span><span id="line-5353"> region.flush(true);</span>
<span class="source-line-no">5354</span><span id="line-5354"> } catch (Exception e) {</span>
<span class="source-line-no">5355</span><span id="line-5355"> e.printStackTrace();</span>
<span class="source-line-no">5356</span><span id="line-5356"> }</span>
<span class="source-line-no">5357</span><span id="line-5357"> }</span>
<span class="source-line-no">5358</span><span id="line-5358"> }</span>
<span class="source-line-no">5359</span><span id="line-5359"> };</span>
<span class="source-line-no">5360</span><span id="line-5360"></span>
<span class="source-line-no">5361</span><span id="line-5361"> // After all append finished, the value will append to threadNum *</span>
<span class="source-line-no">5362</span><span id="line-5362"> // appendCounter Appender.CHAR</span>
<span class="source-line-no">5363</span><span id="line-5363"> int threadNum = 20;</span>
<span class="source-line-no">5364</span><span id="line-5364"> int appendCounter = 100;</span>
<span class="source-line-no">5365</span><span id="line-5365"> byte[] expected = new byte[threadNum * appendCounter];</span>
<span class="source-line-no">5366</span><span id="line-5366"> for (int i = 0; i &lt; threadNum * appendCounter; i++) {</span>
<span class="source-line-no">5367</span><span id="line-5367"> System.arraycopy(Appender.CHAR, 0, expected, i, 1);</span>
<span class="source-line-no">5368</span><span id="line-5368"> }</span>
<span class="source-line-no">5369</span><span id="line-5369"> Thread[] appenders = new Thread[threadNum];</span>
<span class="source-line-no">5370</span><span id="line-5370"> Thread flushThread = new Thread(flusher);</span>
<span class="source-line-no">5371</span><span id="line-5371"> for (int i = 0; i &lt; threadNum; i++) {</span>
<span class="source-line-no">5372</span><span id="line-5372"> appenders[i] = new Thread(new Appender(this.region, appendCounter));</span>
<span class="source-line-no">5373</span><span id="line-5373"> appenders[i].start();</span>
<span class="source-line-no">5374</span><span id="line-5374"> }</span>
<span class="source-line-no">5375</span><span id="line-5375"> flushThread.start();</span>
<span class="source-line-no">5376</span><span id="line-5376"> for (int i = 0; i &lt; threadNum; i++) {</span>
<span class="source-line-no">5377</span><span id="line-5377"> appenders[i].join();</span>
<span class="source-line-no">5378</span><span id="line-5378"> }</span>
<span class="source-line-no">5379</span><span id="line-5379"></span>
<span class="source-line-no">5380</span><span id="line-5380"> appendDone.set(true);</span>
<span class="source-line-no">5381</span><span id="line-5381"> flushThread.join();</span>
<span class="source-line-no">5382</span><span id="line-5382"></span>
<span class="source-line-no">5383</span><span id="line-5383"> Get get = new Get(Appender.appendRow);</span>
<span class="source-line-no">5384</span><span id="line-5384"> get.addColumn(Appender.family, Appender.qualifier);</span>
<span class="source-line-no">5385</span><span id="line-5385"> get.readVersions(1);</span>
<span class="source-line-no">5386</span><span id="line-5386"> Result res = this.region.get(get);</span>
<span class="source-line-no">5387</span><span id="line-5387"> List&lt;Cell&gt; kvs = res.getColumnCells(Appender.family, Appender.qualifier);</span>
<span class="source-line-no">5388</span><span id="line-5388"></span>
<span class="source-line-no">5389</span><span id="line-5389"> // we just got the latest version</span>
<span class="source-line-no">5390</span><span id="line-5390"> assertEquals(1, kvs.size());</span>
<span class="source-line-no">5391</span><span id="line-5391"> Cell kv = kvs.get(0);</span>
<span class="source-line-no">5392</span><span id="line-5392"> byte[] appendResult = new byte[kv.getValueLength()];</span>
<span class="source-line-no">5393</span><span id="line-5393"> System.arraycopy(kv.getValueArray(), kv.getValueOffset(), appendResult, 0, kv.getValueLength());</span>
<span class="source-line-no">5394</span><span id="line-5394"> assertArrayEquals(expected, appendResult);</span>
<span class="source-line-no">5395</span><span id="line-5395"> }</span>
<span class="source-line-no">5396</span><span id="line-5396"></span>
<span class="source-line-no">5397</span><span id="line-5397"> /**</span>
<span class="source-line-no">5398</span><span id="line-5398"> * Test case to check put function with memstore flushing for same row, same ts</span>
<span class="source-line-no">5399</span><span id="line-5399"> */</span>
<span class="source-line-no">5400</span><span id="line-5400"> @Test</span>
<span class="source-line-no">5401</span><span id="line-5401"> public void testPutWithMemStoreFlush() throws Exception {</span>
<span class="source-line-no">5402</span><span id="line-5402"> byte[] family = Bytes.toBytes("family");</span>
<span class="source-line-no">5403</span><span id="line-5403"> byte[] qualifier = Bytes.toBytes("qualifier");</span>
<span class="source-line-no">5404</span><span id="line-5404"> byte[] row = Bytes.toBytes("putRow");</span>
<span class="source-line-no">5405</span><span id="line-5405"> byte[] value = null;</span>
<span class="source-line-no">5406</span><span id="line-5406"> this.region = initHRegion(tableName, method, CONF, family);</span>
<span class="source-line-no">5407</span><span id="line-5407"> Put put = null;</span>
<span class="source-line-no">5408</span><span id="line-5408"> Get get = null;</span>
<span class="source-line-no">5409</span><span id="line-5409"> List&lt;Cell&gt; kvs = null;</span>
<span class="source-line-no">5410</span><span id="line-5410"> Result res = null;</span>
<span class="source-line-no">5411</span><span id="line-5411"></span>
<span class="source-line-no">5412</span><span id="line-5412"> put = new Put(row);</span>
<span class="source-line-no">5413</span><span id="line-5413"> value = Bytes.toBytes("value0");</span>
<span class="source-line-no">5414</span><span id="line-5414"> put.addColumn(family, qualifier, 1234567L, value);</span>
<span class="source-line-no">5415</span><span id="line-5415"> region.put(put);</span>
<span class="source-line-no">5416</span><span id="line-5416"> get = new Get(row);</span>
<span class="source-line-no">5417</span><span id="line-5417"> get.addColumn(family, qualifier);</span>
<span class="source-line-no">5418</span><span id="line-5418"> get.readAllVersions();</span>
<span class="source-line-no">5419</span><span id="line-5419"> res = this.region.get(get);</span>
<span class="source-line-no">5420</span><span id="line-5420"> kvs = res.getColumnCells(family, qualifier);</span>
<span class="source-line-no">5421</span><span id="line-5421"> assertEquals(1, kvs.size());</span>
<span class="source-line-no">5422</span><span id="line-5422"> assertArrayEquals(Bytes.toBytes("value0"), CellUtil.cloneValue(kvs.get(0)));</span>
<span class="source-line-no">5423</span><span id="line-5423"></span>
<span class="source-line-no">5424</span><span id="line-5424"> region.flush(true);</span>
<span class="source-line-no">5425</span><span id="line-5425"> get = new Get(row);</span>
<span class="source-line-no">5426</span><span id="line-5426"> get.addColumn(family, qualifier);</span>
<span class="source-line-no">5427</span><span id="line-5427"> get.readAllVersions();</span>
<span class="source-line-no">5428</span><span id="line-5428"> res = this.region.get(get);</span>
<span class="source-line-no">5429</span><span id="line-5429"> kvs = res.getColumnCells(family, qualifier);</span>
<span class="source-line-no">5430</span><span id="line-5430"> assertEquals(1, kvs.size());</span>
<span class="source-line-no">5431</span><span id="line-5431"> assertArrayEquals(Bytes.toBytes("value0"), CellUtil.cloneValue(kvs.get(0)));</span>
<span class="source-line-no">5432</span><span id="line-5432"></span>
<span class="source-line-no">5433</span><span id="line-5433"> put = new Put(row);</span>
<span class="source-line-no">5434</span><span id="line-5434"> value = Bytes.toBytes("value1");</span>
<span class="source-line-no">5435</span><span id="line-5435"> put.addColumn(family, qualifier, 1234567L, value);</span>
<span class="source-line-no">5436</span><span id="line-5436"> region.put(put);</span>
<span class="source-line-no">5437</span><span id="line-5437"> get = new Get(row);</span>
<span class="source-line-no">5438</span><span id="line-5438"> get.addColumn(family, qualifier);</span>
<span class="source-line-no">5439</span><span id="line-5439"> get.readAllVersions();</span>
<span class="source-line-no">5440</span><span id="line-5440"> res = this.region.get(get);</span>
<span class="source-line-no">5441</span><span id="line-5441"> kvs = res.getColumnCells(family, qualifier);</span>
<span class="source-line-no">5442</span><span id="line-5442"> assertEquals(1, kvs.size());</span>
<span class="source-line-no">5443</span><span id="line-5443"> assertArrayEquals(Bytes.toBytes("value1"), CellUtil.cloneValue(kvs.get(0)));</span>
<span class="source-line-no">5444</span><span id="line-5444"></span>
<span class="source-line-no">5445</span><span id="line-5445"> region.flush(true);</span>
<span class="source-line-no">5446</span><span id="line-5446"> get = new Get(row);</span>
<span class="source-line-no">5447</span><span id="line-5447"> get.addColumn(family, qualifier);</span>
<span class="source-line-no">5448</span><span id="line-5448"> get.readAllVersions();</span>
<span class="source-line-no">5449</span><span id="line-5449"> res = this.region.get(get);</span>
<span class="source-line-no">5450</span><span id="line-5450"> kvs = res.getColumnCells(family, qualifier);</span>
<span class="source-line-no">5451</span><span id="line-5451"> assertEquals(1, kvs.size());</span>
<span class="source-line-no">5452</span><span id="line-5452"> assertArrayEquals(Bytes.toBytes("value1"), CellUtil.cloneValue(kvs.get(0)));</span>
<span class="source-line-no">5453</span><span id="line-5453"> }</span>
<span class="source-line-no">5454</span><span id="line-5454"></span>
<span class="source-line-no">5455</span><span id="line-5455"> /**</span>
<span class="source-line-no">5456</span><span id="line-5456"> * For this test,the spied {@link AsyncFSWAL} can not work properly because of a Mockito defect</span>
<span class="source-line-no">5457</span><span id="line-5457"> * that can not deal with classes which have a field of an inner class. See discussions in</span>
<span class="source-line-no">5458</span><span id="line-5458"> * HBASE-15536.When we reuse the code of {@link AsyncFSWAL} for {@link FSHLog}, this test could</span>
<span class="source-line-no">5459</span><span id="line-5459"> * not work for {@link FSHLog} also.</span>
<span class="source-line-no">5460</span><span id="line-5460"> */</span>
<span class="source-line-no">5461</span><span id="line-5461"> @Test</span>
<span class="source-line-no">5462</span><span id="line-5462"> @Ignore</span>
<span class="source-line-no">5463</span><span id="line-5463"> public void testDurability() throws Exception {</span>
<span class="source-line-no">5464</span><span id="line-5464"> // there are 5 x 5 cases:</span>
<span class="source-line-no">5465</span><span id="line-5465"> // table durability(SYNC,FSYNC,ASYC,SKIP,USE_DEFAULT) x mutation</span>
<span class="source-line-no">5466</span><span id="line-5466"> // durability(SYNC,FSYNC,ASYC,SKIP,USE_DEFAULT)</span>
<span class="source-line-no">5467</span><span id="line-5467"></span>
<span class="source-line-no">5468</span><span id="line-5468"> // expected cases for append and sync wal</span>
<span class="source-line-no">5469</span><span id="line-5469"> durabilityTest(method, Durability.SYNC_WAL, Durability.SYNC_WAL, 0, true, true, false);</span>
<span class="source-line-no">5470</span><span id="line-5470"> durabilityTest(method, Durability.SYNC_WAL, Durability.FSYNC_WAL, 0, true, true, false);</span>
<span class="source-line-no">5471</span><span id="line-5471"> durabilityTest(method, Durability.SYNC_WAL, Durability.USE_DEFAULT, 0, true, true, false);</span>
<span class="source-line-no">5472</span><span id="line-5472"></span>
<span class="source-line-no">5473</span><span id="line-5473"> durabilityTest(method, Durability.FSYNC_WAL, Durability.SYNC_WAL, 0, true, true, false);</span>
<span class="source-line-no">5474</span><span id="line-5474"> durabilityTest(method, Durability.FSYNC_WAL, Durability.FSYNC_WAL, 0, true, true, false);</span>
<span class="source-line-no">5475</span><span id="line-5475"> durabilityTest(method, Durability.FSYNC_WAL, Durability.USE_DEFAULT, 0, true, true, false);</span>
<span class="source-line-no">5476</span><span id="line-5476"></span>
<span class="source-line-no">5477</span><span id="line-5477"> durabilityTest(method, Durability.ASYNC_WAL, Durability.SYNC_WAL, 0, true, true, false);</span>
<span class="source-line-no">5478</span><span id="line-5478"> durabilityTest(method, Durability.ASYNC_WAL, Durability.FSYNC_WAL, 0, true, true, false);</span>
<span class="source-line-no">5479</span><span id="line-5479"></span>
<span class="source-line-no">5480</span><span id="line-5480"> durabilityTest(method, Durability.SKIP_WAL, Durability.SYNC_WAL, 0, true, true, false);</span>
<span class="source-line-no">5481</span><span id="line-5481"> durabilityTest(method, Durability.SKIP_WAL, Durability.FSYNC_WAL, 0, true, true, false);</span>
<span class="source-line-no">5482</span><span id="line-5482"></span>
<span class="source-line-no">5483</span><span id="line-5483"> durabilityTest(method, Durability.USE_DEFAULT, Durability.SYNC_WAL, 0, true, true, false);</span>
<span class="source-line-no">5484</span><span id="line-5484"> durabilityTest(method, Durability.USE_DEFAULT, Durability.FSYNC_WAL, 0, true, true, false);</span>
<span class="source-line-no">5485</span><span id="line-5485"> durabilityTest(method, Durability.USE_DEFAULT, Durability.USE_DEFAULT, 0, true, true, false);</span>
<span class="source-line-no">5486</span><span id="line-5486"></span>
<span class="source-line-no">5487</span><span id="line-5487"> // expected cases for async wal</span>
<span class="source-line-no">5488</span><span id="line-5488"> durabilityTest(method, Durability.SYNC_WAL, Durability.ASYNC_WAL, 0, true, false, false);</span>
<span class="source-line-no">5489</span><span id="line-5489"> durabilityTest(method, Durability.FSYNC_WAL, Durability.ASYNC_WAL, 0, true, false, false);</span>
<span class="source-line-no">5490</span><span id="line-5490"> durabilityTest(method, Durability.ASYNC_WAL, Durability.ASYNC_WAL, 0, true, false, false);</span>
<span class="source-line-no">5491</span><span id="line-5491"> durabilityTest(method, Durability.SKIP_WAL, Durability.ASYNC_WAL, 0, true, false, false);</span>
<span class="source-line-no">5492</span><span id="line-5492"> durabilityTest(method, Durability.USE_DEFAULT, Durability.ASYNC_WAL, 0, true, false, false);</span>
<span class="source-line-no">5493</span><span id="line-5493"> durabilityTest(method, Durability.ASYNC_WAL, Durability.USE_DEFAULT, 0, true, false, false);</span>
<span class="source-line-no">5494</span><span id="line-5494"></span>
<span class="source-line-no">5495</span><span id="line-5495"> durabilityTest(method, Durability.SYNC_WAL, Durability.ASYNC_WAL, 5000, true, false, true);</span>
<span class="source-line-no">5496</span><span id="line-5496"> durabilityTest(method, Durability.FSYNC_WAL, Durability.ASYNC_WAL, 5000, true, false, true);</span>
<span class="source-line-no">5497</span><span id="line-5497"> durabilityTest(method, Durability.ASYNC_WAL, Durability.ASYNC_WAL, 5000, true, false, true);</span>
<span class="source-line-no">5498</span><span id="line-5498"> durabilityTest(method, Durability.SKIP_WAL, Durability.ASYNC_WAL, 5000, true, false, true);</span>
<span class="source-line-no">5499</span><span id="line-5499"> durabilityTest(method, Durability.USE_DEFAULT, Durability.ASYNC_WAL, 5000, true, false, true);</span>
<span class="source-line-no">5500</span><span id="line-5500"> durabilityTest(method, Durability.ASYNC_WAL, Durability.USE_DEFAULT, 5000, true, false, true);</span>
<span class="source-line-no">5501</span><span id="line-5501"></span>
<span class="source-line-no">5502</span><span id="line-5502"> // expect skip wal cases</span>
<span class="source-line-no">5503</span><span id="line-5503"> durabilityTest(method, Durability.SYNC_WAL, Durability.SKIP_WAL, 0, false, false, false);</span>
<span class="source-line-no">5504</span><span id="line-5504"> durabilityTest(method, Durability.FSYNC_WAL, Durability.SKIP_WAL, 0, false, false, false);</span>
<span class="source-line-no">5505</span><span id="line-5505"> durabilityTest(method, Durability.ASYNC_WAL, Durability.SKIP_WAL, 0, false, false, false);</span>
<span class="source-line-no">5506</span><span id="line-5506"> durabilityTest(method, Durability.SKIP_WAL, Durability.SKIP_WAL, 0, false, false, false);</span>
<span class="source-line-no">5507</span><span id="line-5507"> durabilityTest(method, Durability.USE_DEFAULT, Durability.SKIP_WAL, 0, false, false, false);</span>
<span class="source-line-no">5508</span><span id="line-5508"> durabilityTest(method, Durability.SKIP_WAL, Durability.USE_DEFAULT, 0, false, false, false);</span>
<span class="source-line-no">5509</span><span id="line-5509"></span>
<span class="source-line-no">5510</span><span id="line-5510"> }</span>
<span class="source-line-no">5511</span><span id="line-5511"></span>
<span class="source-line-no">5512</span><span id="line-5512"> private void durabilityTest(String method, Durability tableDurability,</span>
<span class="source-line-no">5513</span><span id="line-5513"> Durability mutationDurability, long timeout, boolean expectAppend, final boolean expectSync,</span>
<span class="source-line-no">5514</span><span id="line-5514"> final boolean expectSyncFromLogSyncer) throws Exception {</span>
<span class="source-line-no">5515</span><span id="line-5515"> Configuration conf = HBaseConfiguration.create(CONF);</span>
<span class="source-line-no">5516</span><span id="line-5516"> conf.setLong(AbstractFSWAL.WAL_SHUTDOWN_WAIT_TIMEOUT_MS, 60 * 60 * 1000);</span>
<span class="source-line-no">5517</span><span id="line-5517"> method = method + "_" + tableDurability.name() + "_" + mutationDurability.name();</span>
<span class="source-line-no">5518</span><span id="line-5518"> byte[] family = Bytes.toBytes("family");</span>
<span class="source-line-no">5519</span><span id="line-5519"> Path logDir = new Path(new Path(dir + method), "log");</span>
<span class="source-line-no">5520</span><span id="line-5520"> final Configuration walConf = new Configuration(conf);</span>
<span class="source-line-no">5521</span><span id="line-5521"> CommonFSUtils.setRootDir(walConf, logDir);</span>
<span class="source-line-no">5522</span><span id="line-5522"> // XXX: The spied AsyncFSWAL can not work properly because of a Mockito defect that can not</span>
<span class="source-line-no">5523</span><span id="line-5523"> // deal with classes which have a field of an inner class. See discussions in HBASE-15536.</span>
<span class="source-line-no">5524</span><span id="line-5524"> walConf.set(WALFactory.WAL_PROVIDER, "filesystem");</span>
<span class="source-line-no">5525</span><span id="line-5525"> final WALFactory wals = new WALFactory(walConf, HBaseTestingUtil.getRandomUUID().toString());</span>
<span class="source-line-no">5526</span><span id="line-5526"> final WAL wal = spy(wals.getWAL(RegionInfoBuilder.newBuilder(tableName).build()));</span>
<span class="source-line-no">5527</span><span id="line-5527"> this.region = initHRegion(tableName, HConstants.EMPTY_START_ROW, HConstants.EMPTY_END_ROW, CONF,</span>
<span class="source-line-no">5528</span><span id="line-5528"> false, tableDurability, wal, new byte[][] { family });</span>
<span class="source-line-no">5529</span><span id="line-5529"></span>
<span class="source-line-no">5530</span><span id="line-5530"> Put put = new Put(Bytes.toBytes("r1"));</span>
<span class="source-line-no">5531</span><span id="line-5531"> put.addColumn(family, Bytes.toBytes("q1"), Bytes.toBytes("v1"));</span>
<span class="source-line-no">5532</span><span id="line-5532"> put.setDurability(mutationDurability);</span>
<span class="source-line-no">5533</span><span id="line-5533"> region.put(put);</span>
<span class="source-line-no">5534</span><span id="line-5534"></span>
<span class="source-line-no">5535</span><span id="line-5535"> // verify append called or not</span>
<span class="source-line-no">5536</span><span id="line-5536"> verify(wal, expectAppend ? times(1) : never()).appendData((RegionInfo) any(),</span>
<span class="source-line-no">5537</span><span id="line-5537"> (WALKeyImpl) any(), (WALEdit) any());</span>
<span class="source-line-no">5538</span><span id="line-5538"></span>
<span class="source-line-no">5539</span><span id="line-5539"> // verify sync called or not</span>
<span class="source-line-no">5540</span><span id="line-5540"> if (expectSync || expectSyncFromLogSyncer) {</span>
<span class="source-line-no">5541</span><span id="line-5541"> TEST_UTIL.waitFor(timeout, new Waiter.Predicate&lt;Exception&gt;() {</span>
<span class="source-line-no">5542</span><span id="line-5542"> @Override</span>
<span class="source-line-no">5543</span><span id="line-5543"> public boolean evaluate() throws Exception {</span>
<span class="source-line-no">5544</span><span id="line-5544"> try {</span>
<span class="source-line-no">5545</span><span id="line-5545"> if (expectSync) {</span>
<span class="source-line-no">5546</span><span id="line-5546"> verify(wal, times(1)).sync(anyLong()); // Hregion calls this one</span>
<span class="source-line-no">5547</span><span id="line-5547"> } else if (expectSyncFromLogSyncer) {</span>
<span class="source-line-no">5548</span><span id="line-5548"> verify(wal, times(1)).sync(); // wal syncer calls this one</span>
<span class="source-line-no">5549</span><span id="line-5549"> }</span>
<span class="source-line-no">5550</span><span id="line-5550"> } catch (Throwable ignore) {</span>
<span class="source-line-no">5551</span><span id="line-5551"> }</span>
<span class="source-line-no">5552</span><span id="line-5552"> return true;</span>
<span class="source-line-no">5553</span><span id="line-5553"> }</span>
<span class="source-line-no">5554</span><span id="line-5554"> });</span>
<span class="source-line-no">5555</span><span id="line-5555"> } else {</span>
<span class="source-line-no">5556</span><span id="line-5556"> // verify(wal, never()).sync(anyLong());</span>
<span class="source-line-no">5557</span><span id="line-5557"> verify(wal, never()).sync();</span>
<span class="source-line-no">5558</span><span id="line-5558"> }</span>
<span class="source-line-no">5559</span><span id="line-5559"></span>
<span class="source-line-no">5560</span><span id="line-5560"> HBaseTestingUtil.closeRegionAndWAL(this.region);</span>
<span class="source-line-no">5561</span><span id="line-5561"> wals.close();</span>
<span class="source-line-no">5562</span><span id="line-5562"> this.region = null;</span>
<span class="source-line-no">5563</span><span id="line-5563"> }</span>
<span class="source-line-no">5564</span><span id="line-5564"></span>
<span class="source-line-no">5565</span><span id="line-5565"> @Test</span>
<span class="source-line-no">5566</span><span id="line-5566"> public void testRegionReplicaSecondary() throws IOException {</span>
<span class="source-line-no">5567</span><span id="line-5567"> // create a primary region, load some data and flush</span>
<span class="source-line-no">5568</span><span id="line-5568"> // create a secondary region, and do a get against that</span>
<span class="source-line-no">5569</span><span id="line-5569"> Path rootDir = new Path(dir + name.getMethodName());</span>
<span class="source-line-no">5570</span><span id="line-5570"> CommonFSUtils.setRootDir(TEST_UTIL.getConfiguration(), rootDir);</span>
<span class="source-line-no">5571</span><span id="line-5571"></span>
<span class="source-line-no">5572</span><span id="line-5572"> byte[][] families =</span>
<span class="source-line-no">5573</span><span id="line-5573"> new byte[][] { Bytes.toBytes("cf1"), Bytes.toBytes("cf2"), Bytes.toBytes("cf3") };</span>
<span class="source-line-no">5574</span><span id="line-5574"> byte[] cq = Bytes.toBytes("cq");</span>
<span class="source-line-no">5575</span><span id="line-5575"> TableDescriptorBuilder builder =</span>
<span class="source-line-no">5576</span><span id="line-5576"> TableDescriptorBuilder.newBuilder(TableName.valueOf(name.getMethodName()));</span>
<span class="source-line-no">5577</span><span id="line-5577"> for (byte[] family : families) {</span>
<span class="source-line-no">5578</span><span id="line-5578"> builder.setColumnFamily(ColumnFamilyDescriptorBuilder.of(family));</span>
<span class="source-line-no">5579</span><span id="line-5579"> }</span>
<span class="source-line-no">5580</span><span id="line-5580"> TableDescriptor tableDescriptor = builder.build();</span>
<span class="source-line-no">5581</span><span id="line-5581"> long time = EnvironmentEdgeManager.currentTime();</span>
<span class="source-line-no">5582</span><span id="line-5582"> RegionInfo primaryHri = RegionInfoBuilder.newBuilder(tableDescriptor.getTableName())</span>
<span class="source-line-no">5583</span><span id="line-5583"> .setRegionId(time).setReplicaId(0).build();</span>
<span class="source-line-no">5584</span><span id="line-5584"> RegionInfo secondaryHri = RegionInfoBuilder.newBuilder(tableDescriptor.getTableName())</span>
<span class="source-line-no">5585</span><span id="line-5585"> .setRegionId(time).setReplicaId(1).build();</span>
<span class="source-line-no">5586</span><span id="line-5586"></span>
<span class="source-line-no">5587</span><span id="line-5587"> HRegion primaryRegion = null, secondaryRegion = null;</span>
<span class="source-line-no">5588</span><span id="line-5588"></span>
<span class="source-line-no">5589</span><span id="line-5589"> try {</span>
<span class="source-line-no">5590</span><span id="line-5590"> primaryRegion = HBaseTestingUtil.createRegionAndWAL(primaryHri, rootDir,</span>
<span class="source-line-no">5591</span><span id="line-5591"> TEST_UTIL.getConfiguration(), tableDescriptor);</span>
<span class="source-line-no">5592</span><span id="line-5592"></span>
<span class="source-line-no">5593</span><span id="line-5593"> // load some data</span>
<span class="source-line-no">5594</span><span id="line-5594"> putData(primaryRegion, 0, 1000, cq, families);</span>
<span class="source-line-no">5595</span><span id="line-5595"></span>
<span class="source-line-no">5596</span><span id="line-5596"> // flush region</span>
<span class="source-line-no">5597</span><span id="line-5597"> primaryRegion.flush(true);</span>
<span class="source-line-no">5598</span><span id="line-5598"></span>
<span class="source-line-no">5599</span><span id="line-5599"> // open secondary region</span>
<span class="source-line-no">5600</span><span id="line-5600"> secondaryRegion = HRegion.openHRegion(rootDir, secondaryHri, tableDescriptor, null, CONF);</span>
<span class="source-line-no">5601</span><span id="line-5601"></span>
<span class="source-line-no">5602</span><span id="line-5602"> verifyData(secondaryRegion, 0, 1000, cq, families);</span>
<span class="source-line-no">5603</span><span id="line-5603"> } finally {</span>
<span class="source-line-no">5604</span><span id="line-5604"> if (primaryRegion != null) {</span>
<span class="source-line-no">5605</span><span id="line-5605"> HBaseTestingUtil.closeRegionAndWAL(primaryRegion);</span>
<span class="source-line-no">5606</span><span id="line-5606"> }</span>
<span class="source-line-no">5607</span><span id="line-5607"> if (secondaryRegion != null) {</span>
<span class="source-line-no">5608</span><span id="line-5608"> HBaseTestingUtil.closeRegionAndWAL(secondaryRegion);</span>
<span class="source-line-no">5609</span><span id="line-5609"> }</span>
<span class="source-line-no">5610</span><span id="line-5610"> }</span>
<span class="source-line-no">5611</span><span id="line-5611"> }</span>
<span class="source-line-no">5612</span><span id="line-5612"></span>
<span class="source-line-no">5613</span><span id="line-5613"> @Test</span>
<span class="source-line-no">5614</span><span id="line-5614"> public void testRegionReplicaSecondaryIsReadOnly() throws IOException {</span>
<span class="source-line-no">5615</span><span id="line-5615"> // create a primary region, load some data and flush</span>
<span class="source-line-no">5616</span><span id="line-5616"> // create a secondary region, and do a put against that</span>
<span class="source-line-no">5617</span><span id="line-5617"> Path rootDir = new Path(dir + name.getMethodName());</span>
<span class="source-line-no">5618</span><span id="line-5618"> CommonFSUtils.setRootDir(TEST_UTIL.getConfiguration(), rootDir);</span>
<span class="source-line-no">5619</span><span id="line-5619"></span>
<span class="source-line-no">5620</span><span id="line-5620"> byte[][] families =</span>
<span class="source-line-no">5621</span><span id="line-5621"> new byte[][] { Bytes.toBytes("cf1"), Bytes.toBytes("cf2"), Bytes.toBytes("cf3") };</span>
<span class="source-line-no">5622</span><span id="line-5622"> byte[] cq = Bytes.toBytes("cq");</span>
<span class="source-line-no">5623</span><span id="line-5623"> TableDescriptorBuilder builder =</span>
<span class="source-line-no">5624</span><span id="line-5624"> TableDescriptorBuilder.newBuilder(TableName.valueOf(name.getMethodName()));</span>
<span class="source-line-no">5625</span><span id="line-5625"> for (byte[] family : families) {</span>
<span class="source-line-no">5626</span><span id="line-5626"> builder.setColumnFamily(ColumnFamilyDescriptorBuilder.of(family));</span>
<span class="source-line-no">5627</span><span id="line-5627"> }</span>
<span class="source-line-no">5628</span><span id="line-5628"> TableDescriptor tableDescriptor = builder.build();</span>
<span class="source-line-no">5629</span><span id="line-5629"> long time = EnvironmentEdgeManager.currentTime();</span>
<span class="source-line-no">5630</span><span id="line-5630"> RegionInfo primaryHri = RegionInfoBuilder.newBuilder(tableDescriptor.getTableName())</span>
<span class="source-line-no">5631</span><span id="line-5631"> .setRegionId(time).setReplicaId(0).build();</span>
<span class="source-line-no">5632</span><span id="line-5632"> RegionInfo secondaryHri = RegionInfoBuilder.newBuilder(tableDescriptor.getTableName())</span>
<span class="source-line-no">5633</span><span id="line-5633"> .setRegionId(time).setReplicaId(1).build();</span>
<span class="source-line-no">5634</span><span id="line-5634"></span>
<span class="source-line-no">5635</span><span id="line-5635"> HRegion primaryRegion = null, secondaryRegion = null;</span>
<span class="source-line-no">5636</span><span id="line-5636"></span>
<span class="source-line-no">5637</span><span id="line-5637"> try {</span>
<span class="source-line-no">5638</span><span id="line-5638"> primaryRegion = HBaseTestingUtil.createRegionAndWAL(primaryHri, rootDir,</span>
<span class="source-line-no">5639</span><span id="line-5639"> TEST_UTIL.getConfiguration(), tableDescriptor);</span>
<span class="source-line-no">5640</span><span id="line-5640"></span>
<span class="source-line-no">5641</span><span id="line-5641"> // load some data</span>
<span class="source-line-no">5642</span><span id="line-5642"> putData(primaryRegion, 0, 1000, cq, families);</span>
<span class="source-line-no">5643</span><span id="line-5643"></span>
<span class="source-line-no">5644</span><span id="line-5644"> // flush region</span>
<span class="source-line-no">5645</span><span id="line-5645"> primaryRegion.flush(true);</span>
<span class="source-line-no">5646</span><span id="line-5646"></span>
<span class="source-line-no">5647</span><span id="line-5647"> // open secondary region</span>
<span class="source-line-no">5648</span><span id="line-5648"> secondaryRegion = HRegion.openHRegion(rootDir, secondaryHri, tableDescriptor, null, CONF);</span>
<span class="source-line-no">5649</span><span id="line-5649"></span>
<span class="source-line-no">5650</span><span id="line-5650"> try {</span>
<span class="source-line-no">5651</span><span id="line-5651"> putData(secondaryRegion, 0, 1000, cq, families);</span>
<span class="source-line-no">5652</span><span id="line-5652"> fail("Should have thrown exception");</span>
<span class="source-line-no">5653</span><span id="line-5653"> } catch (IOException ex) {</span>
<span class="source-line-no">5654</span><span id="line-5654"> // expected</span>
<span class="source-line-no">5655</span><span id="line-5655"> }</span>
<span class="source-line-no">5656</span><span id="line-5656"> } finally {</span>
<span class="source-line-no">5657</span><span id="line-5657"> if (primaryRegion != null) {</span>
<span class="source-line-no">5658</span><span id="line-5658"> HBaseTestingUtil.closeRegionAndWAL(primaryRegion);</span>
<span class="source-line-no">5659</span><span id="line-5659"> }</span>
<span class="source-line-no">5660</span><span id="line-5660"> if (secondaryRegion != null) {</span>
<span class="source-line-no">5661</span><span id="line-5661"> HBaseTestingUtil.closeRegionAndWAL(secondaryRegion);</span>
<span class="source-line-no">5662</span><span id="line-5662"> }</span>
<span class="source-line-no">5663</span><span id="line-5663"> }</span>
<span class="source-line-no">5664</span><span id="line-5664"> }</span>
<span class="source-line-no">5665</span><span id="line-5665"></span>
<span class="source-line-no">5666</span><span id="line-5666"> static WALFactory createWALFactory(Configuration conf, Path rootDir) throws IOException {</span>
<span class="source-line-no">5667</span><span id="line-5667"> Configuration confForWAL = new Configuration(conf);</span>
<span class="source-line-no">5668</span><span id="line-5668"> confForWAL.set(HConstants.HBASE_DIR, rootDir.toString());</span>
<span class="source-line-no">5669</span><span id="line-5669"> return new WALFactory(confForWAL, "hregion-" + RandomStringUtils.randomNumeric(8));</span>
<span class="source-line-no">5670</span><span id="line-5670"> }</span>
<span class="source-line-no">5671</span><span id="line-5671"></span>
<span class="source-line-no">5672</span><span id="line-5672"> @Test</span>
<span class="source-line-no">5673</span><span id="line-5673"> public void testCompactionFromPrimary() throws IOException {</span>
<span class="source-line-no">5674</span><span id="line-5674"> Path rootDir = new Path(dir + name.getMethodName());</span>
<span class="source-line-no">5675</span><span id="line-5675"> CommonFSUtils.setRootDir(TEST_UTIL.getConfiguration(), rootDir);</span>
<span class="source-line-no">5676</span><span id="line-5676"></span>
<span class="source-line-no">5677</span><span id="line-5677"> byte[][] families =</span>
<span class="source-line-no">5678</span><span id="line-5678"> new byte[][] { Bytes.toBytes("cf1"), Bytes.toBytes("cf2"), Bytes.toBytes("cf3") };</span>
<span class="source-line-no">5679</span><span id="line-5679"> byte[] cq = Bytes.toBytes("cq");</span>
<span class="source-line-no">5680</span><span id="line-5680"> TableDescriptorBuilder builder =</span>
<span class="source-line-no">5681</span><span id="line-5681"> TableDescriptorBuilder.newBuilder(TableName.valueOf(name.getMethodName()));</span>
<span class="source-line-no">5682</span><span id="line-5682"> for (byte[] family : families) {</span>
<span class="source-line-no">5683</span><span id="line-5683"> builder.setColumnFamily(ColumnFamilyDescriptorBuilder.of(family));</span>
<span class="source-line-no">5684</span><span id="line-5684"> }</span>
<span class="source-line-no">5685</span><span id="line-5685"> TableDescriptor tableDescriptor = builder.build();</span>
<span class="source-line-no">5686</span><span id="line-5686"> long time = EnvironmentEdgeManager.currentTime();</span>
<span class="source-line-no">5687</span><span id="line-5687"> RegionInfo primaryHri = RegionInfoBuilder.newBuilder(tableDescriptor.getTableName())</span>
<span class="source-line-no">5688</span><span id="line-5688"> .setRegionId(time).setReplicaId(0).build();</span>
<span class="source-line-no">5689</span><span id="line-5689"> RegionInfo secondaryHri = RegionInfoBuilder.newBuilder(tableDescriptor.getTableName())</span>
<span class="source-line-no">5690</span><span id="line-5690"> .setRegionId(time).setReplicaId(1).build();</span>
<span class="source-line-no">5691</span><span id="line-5691"></span>
<span class="source-line-no">5692</span><span id="line-5692"> HRegion primaryRegion = null, secondaryRegion = null;</span>
<span class="source-line-no">5693</span><span id="line-5693"></span>
<span class="source-line-no">5694</span><span id="line-5694"> try {</span>
<span class="source-line-no">5695</span><span id="line-5695"> primaryRegion = HBaseTestingUtil.createRegionAndWAL(primaryHri, rootDir,</span>
<span class="source-line-no">5696</span><span id="line-5696"> TEST_UTIL.getConfiguration(), tableDescriptor);</span>
<span class="source-line-no">5697</span><span id="line-5697"></span>
<span class="source-line-no">5698</span><span id="line-5698"> // load some data</span>
<span class="source-line-no">5699</span><span id="line-5699"> putData(primaryRegion, 0, 1000, cq, families);</span>
<span class="source-line-no">5700</span><span id="line-5700"></span>
<span class="source-line-no">5701</span><span id="line-5701"> // flush region</span>
<span class="source-line-no">5702</span><span id="line-5702"> primaryRegion.flush(true);</span>
<span class="source-line-no">5703</span><span id="line-5703"></span>
<span class="source-line-no">5704</span><span id="line-5704"> // open secondary region</span>
<span class="source-line-no">5705</span><span id="line-5705"> secondaryRegion = HRegion.openHRegion(rootDir, secondaryHri, tableDescriptor, null, CONF);</span>
<span class="source-line-no">5706</span><span id="line-5706"></span>
<span class="source-line-no">5707</span><span id="line-5707"> // move the file of the primary region to the archive, simulating a compaction</span>
<span class="source-line-no">5708</span><span id="line-5708"> Collection&lt;HStoreFile&gt; storeFiles = primaryRegion.getStore(families[0]).getStorefiles();</span>
<span class="source-line-no">5709</span><span id="line-5709"> primaryRegion.getRegionFileSystem().removeStoreFiles(Bytes.toString(families[0]), storeFiles);</span>
<span class="source-line-no">5710</span><span id="line-5710"> Collection&lt;StoreFileInfo&gt; storeFileInfos =</span>
<span class="source-line-no">5711</span><span id="line-5711"> primaryRegion.getRegionFileSystem().getStoreFiles(Bytes.toString(families[0]));</span>
<span class="source-line-no">5712</span><span id="line-5712"> Assert.assertTrue(storeFileInfos == null || storeFileInfos.isEmpty());</span>
<span class="source-line-no">5713</span><span id="line-5713"></span>
<span class="source-line-no">5714</span><span id="line-5714"> verifyData(secondaryRegion, 0, 1000, cq, families);</span>
<span class="source-line-no">5715</span><span id="line-5715"> } finally {</span>
<span class="source-line-no">5716</span><span id="line-5716"> if (primaryRegion != null) {</span>
<span class="source-line-no">5717</span><span id="line-5717"> HBaseTestingUtil.closeRegionAndWAL(primaryRegion);</span>
<span class="source-line-no">5718</span><span id="line-5718"> }</span>
<span class="source-line-no">5719</span><span id="line-5719"> if (secondaryRegion != null) {</span>
<span class="source-line-no">5720</span><span id="line-5720"> HBaseTestingUtil.closeRegionAndWAL(secondaryRegion);</span>
<span class="source-line-no">5721</span><span id="line-5721"> }</span>
<span class="source-line-no">5722</span><span id="line-5722"> }</span>
<span class="source-line-no">5723</span><span id="line-5723"> }</span>
<span class="source-line-no">5724</span><span id="line-5724"></span>
<span class="source-line-no">5725</span><span id="line-5725"> private void putData(int startRow, int numRows, byte[] qf, byte[]... families)</span>
<span class="source-line-no">5726</span><span id="line-5726"> throws IOException {</span>
<span class="source-line-no">5727</span><span id="line-5727"> putData(this.region, startRow, numRows, qf, families);</span>
<span class="source-line-no">5728</span><span id="line-5728"> }</span>
<span class="source-line-no">5729</span><span id="line-5729"></span>
<span class="source-line-no">5730</span><span id="line-5730"> private void putData(HRegion region, int startRow, int numRows, byte[] qf, byte[]... families)</span>
<span class="source-line-no">5731</span><span id="line-5731"> throws IOException {</span>
<span class="source-line-no">5732</span><span id="line-5732"> putData(region, Durability.SKIP_WAL, startRow, numRows, qf, families);</span>
<span class="source-line-no">5733</span><span id="line-5733"> }</span>
<span class="source-line-no">5734</span><span id="line-5734"></span>
<span class="source-line-no">5735</span><span id="line-5735"> static void putData(HRegion region, Durability durability, int startRow, int numRows, byte[] qf,</span>
<span class="source-line-no">5736</span><span id="line-5736"> byte[]... families) throws IOException {</span>
<span class="source-line-no">5737</span><span id="line-5737"> for (int i = startRow; i &lt; startRow + numRows; i++) {</span>
<span class="source-line-no">5738</span><span id="line-5738"> Put put = new Put(Bytes.toBytes("" + i));</span>
<span class="source-line-no">5739</span><span id="line-5739"> put.setDurability(durability);</span>
<span class="source-line-no">5740</span><span id="line-5740"> for (byte[] family : families) {</span>
<span class="source-line-no">5741</span><span id="line-5741"> put.addColumn(family, qf, null);</span>
<span class="source-line-no">5742</span><span id="line-5742"> }</span>
<span class="source-line-no">5743</span><span id="line-5743"> region.put(put);</span>
<span class="source-line-no">5744</span><span id="line-5744"> LOG.info(put.toString());</span>
<span class="source-line-no">5745</span><span id="line-5745"> }</span>
<span class="source-line-no">5746</span><span id="line-5746"> }</span>
<span class="source-line-no">5747</span><span id="line-5747"></span>
<span class="source-line-no">5748</span><span id="line-5748"> static void verifyData(HRegion newReg, int startRow, int numRows, byte[] qf, byte[]... families)</span>
<span class="source-line-no">5749</span><span id="line-5749"> throws IOException {</span>
<span class="source-line-no">5750</span><span id="line-5750"> for (int i = startRow; i &lt; startRow + numRows; i++) {</span>
<span class="source-line-no">5751</span><span id="line-5751"> byte[] row = Bytes.toBytes("" + i);</span>
<span class="source-line-no">5752</span><span id="line-5752"> Get get = new Get(row);</span>
<span class="source-line-no">5753</span><span id="line-5753"> for (byte[] family : families) {</span>
<span class="source-line-no">5754</span><span id="line-5754"> get.addColumn(family, qf);</span>
<span class="source-line-no">5755</span><span id="line-5755"> }</span>
<span class="source-line-no">5756</span><span id="line-5756"> Result result = newReg.get(get);</span>
<span class="source-line-no">5757</span><span id="line-5757"> Cell[] raw = result.rawCells();</span>
<span class="source-line-no">5758</span><span id="line-5758"> assertEquals(families.length, result.size());</span>
<span class="source-line-no">5759</span><span id="line-5759"> for (int j = 0; j &lt; families.length; j++) {</span>
<span class="source-line-no">5760</span><span id="line-5760"> assertTrue(CellUtil.matchingRows(raw[j], row));</span>
<span class="source-line-no">5761</span><span id="line-5761"> assertTrue(CellUtil.matchingFamily(raw[j], families[j]));</span>
<span class="source-line-no">5762</span><span id="line-5762"> assertTrue(CellUtil.matchingQualifier(raw[j], qf));</span>
<span class="source-line-no">5763</span><span id="line-5763"> }</span>
<span class="source-line-no">5764</span><span id="line-5764"> }</span>
<span class="source-line-no">5765</span><span id="line-5765"> }</span>
<span class="source-line-no">5766</span><span id="line-5766"></span>
<span class="source-line-no">5767</span><span id="line-5767"> static void assertGet(final HRegion r, final byte[] family, final byte[] k) throws IOException {</span>
<span class="source-line-no">5768</span><span id="line-5768"> // Now I have k, get values out and assert they are as expected.</span>
<span class="source-line-no">5769</span><span id="line-5769"> Get get = new Get(k).addFamily(family).readAllVersions();</span>
<span class="source-line-no">5770</span><span id="line-5770"> Cell[] results = r.get(get).rawCells();</span>
<span class="source-line-no">5771</span><span id="line-5771"> for (int j = 0; j &lt; results.length; j++) {</span>
<span class="source-line-no">5772</span><span id="line-5772"> byte[] tmp = CellUtil.cloneValue(results[j]);</span>
<span class="source-line-no">5773</span><span id="line-5773"> // Row should be equal to value every time.</span>
<span class="source-line-no">5774</span><span id="line-5774"> assertTrue(Bytes.equals(k, tmp));</span>
<span class="source-line-no">5775</span><span id="line-5775"> }</span>
<span class="source-line-no">5776</span><span id="line-5776"> }</span>
<span class="source-line-no">5777</span><span id="line-5777"></span>
<span class="source-line-no">5778</span><span id="line-5778"> /*</span>
<span class="source-line-no">5779</span><span id="line-5779"> * Assert first value in the passed region is &lt;code&gt;firstValue&lt;/code&gt;.</span>
<span class="source-line-no">5780</span><span id="line-5780"> */</span>
<span class="source-line-no">5781</span><span id="line-5781"> protected void assertScan(final HRegion r, final byte[] fs, final byte[] firstValue)</span>
<span class="source-line-no">5782</span><span id="line-5782"> throws IOException {</span>
<span class="source-line-no">5783</span><span id="line-5783"> byte[][] families = { fs };</span>
<span class="source-line-no">5784</span><span id="line-5784"> Scan scan = new Scan();</span>
<span class="source-line-no">5785</span><span id="line-5785"> for (int i = 0; i &lt; families.length; i++)</span>
<span class="source-line-no">5786</span><span id="line-5786"> scan.addFamily(families[i]);</span>
<span class="source-line-no">5787</span><span id="line-5787"> try (InternalScanner s = r.getScanner(scan)) {</span>
<span class="source-line-no">5788</span><span id="line-5788"> List&lt;Cell&gt; curVals = new ArrayList&lt;&gt;();</span>
<span class="source-line-no">5789</span><span id="line-5789"> boolean first = true;</span>
<span class="source-line-no">5790</span><span id="line-5790"> OUTER_LOOP: while (s.next(curVals)) {</span>
<span class="source-line-no">5791</span><span id="line-5791"> for (Cell kv : curVals) {</span>
<span class="source-line-no">5792</span><span id="line-5792"> byte[] val = CellUtil.cloneValue(kv);</span>
<span class="source-line-no">5793</span><span id="line-5793"> byte[] curval = val;</span>
<span class="source-line-no">5794</span><span id="line-5794"> if (first) {</span>
<span class="source-line-no">5795</span><span id="line-5795"> first = false;</span>
<span class="source-line-no">5796</span><span id="line-5796"> assertTrue(Bytes.compareTo(curval, firstValue) == 0);</span>
<span class="source-line-no">5797</span><span id="line-5797"> } else {</span>
<span class="source-line-no">5798</span><span id="line-5798"> // Not asserting anything. Might as well break.</span>
<span class="source-line-no">5799</span><span id="line-5799"> break OUTER_LOOP;</span>
<span class="source-line-no">5800</span><span id="line-5800"> }</span>
<span class="source-line-no">5801</span><span id="line-5801"> }</span>
<span class="source-line-no">5802</span><span id="line-5802"> }</span>
<span class="source-line-no">5803</span><span id="line-5803"> }</span>
<span class="source-line-no">5804</span><span id="line-5804"> }</span>
<span class="source-line-no">5805</span><span id="line-5805"></span>
<span class="source-line-no">5806</span><span id="line-5806"> /**</span>
<span class="source-line-no">5807</span><span id="line-5807"> * Test that we get the expected flush results back</span>
<span class="source-line-no">5808</span><span id="line-5808"> */</span>
<span class="source-line-no">5809</span><span id="line-5809"> @Test</span>
<span class="source-line-no">5810</span><span id="line-5810"> public void testFlushResult() throws IOException {</span>
<span class="source-line-no">5811</span><span id="line-5811"> byte[] family = Bytes.toBytes("family");</span>
<span class="source-line-no">5812</span><span id="line-5812"></span>
<span class="source-line-no">5813</span><span id="line-5813"> this.region = initHRegion(tableName, method, family);</span>
<span class="source-line-no">5814</span><span id="line-5814"></span>
<span class="source-line-no">5815</span><span id="line-5815"> // empty memstore, flush doesn't run</span>
<span class="source-line-no">5816</span><span id="line-5816"> HRegion.FlushResult fr = region.flush(true);</span>
<span class="source-line-no">5817</span><span id="line-5817"> assertFalse(fr.isFlushSucceeded());</span>
<span class="source-line-no">5818</span><span id="line-5818"> assertFalse(fr.isCompactionNeeded());</span>
<span class="source-line-no">5819</span><span id="line-5819"></span>
<span class="source-line-no">5820</span><span id="line-5820"> // Flush enough files to get up to the threshold, doesn't need compactions</span>
<span class="source-line-no">5821</span><span id="line-5821"> for (int i = 0; i &lt; 2; i++) {</span>
<span class="source-line-no">5822</span><span id="line-5822"> Put put = new Put(tableName.toBytes()).addColumn(family, family, tableName.toBytes());</span>
<span class="source-line-no">5823</span><span id="line-5823"> region.put(put);</span>
<span class="source-line-no">5824</span><span id="line-5824"> fr = region.flush(true);</span>
<span class="source-line-no">5825</span><span id="line-5825"> assertTrue(fr.isFlushSucceeded());</span>
<span class="source-line-no">5826</span><span id="line-5826"> assertFalse(fr.isCompactionNeeded());</span>
<span class="source-line-no">5827</span><span id="line-5827"> }</span>
<span class="source-line-no">5828</span><span id="line-5828"></span>
<span class="source-line-no">5829</span><span id="line-5829"> // Two flushes after the threshold, compactions are needed</span>
<span class="source-line-no">5830</span><span id="line-5830"> for (int i = 0; i &lt; 2; i++) {</span>
<span class="source-line-no">5831</span><span id="line-5831"> Put put = new Put(tableName.toBytes()).addColumn(family, family, tableName.toBytes());</span>
<span class="source-line-no">5832</span><span id="line-5832"> region.put(put);</span>
<span class="source-line-no">5833</span><span id="line-5833"> fr = region.flush(true);</span>
<span class="source-line-no">5834</span><span id="line-5834"> assertTrue(fr.isFlushSucceeded());</span>
<span class="source-line-no">5835</span><span id="line-5835"> assertTrue(fr.isCompactionNeeded());</span>
<span class="source-line-no">5836</span><span id="line-5836"> }</span>
<span class="source-line-no">5837</span><span id="line-5837"> }</span>
<span class="source-line-no">5838</span><span id="line-5838"></span>
<span class="source-line-no">5839</span><span id="line-5839"> protected Configuration initSplit() {</span>
<span class="source-line-no">5840</span><span id="line-5840"> // Always compact if there is more than one store file.</span>
<span class="source-line-no">5841</span><span id="line-5841"> CONF.setInt("hbase.hstore.compactionThreshold", 2);</span>
<span class="source-line-no">5842</span><span id="line-5842"></span>
<span class="source-line-no">5843</span><span id="line-5843"> CONF.setInt(HConstants.HBASE_CLIENT_SCANNER_TIMEOUT_PERIOD, 10 * 1000);</span>
<span class="source-line-no">5844</span><span id="line-5844"></span>
<span class="source-line-no">5845</span><span id="line-5845"> // Increase the amount of time between client retries</span>
<span class="source-line-no">5846</span><span id="line-5846"> CONF.setLong("hbase.client.pause", 15 * 1000);</span>
<span class="source-line-no">5847</span><span id="line-5847"></span>
<span class="source-line-no">5848</span><span id="line-5848"> // This size should make it so we always split using the addContent</span>
<span class="source-line-no">5849</span><span id="line-5849"> // below. After adding all data, the first region is 1.3M</span>
<span class="source-line-no">5850</span><span id="line-5850"> CONF.setLong(HConstants.HREGION_MAX_FILESIZE, 1024 * 128);</span>
<span class="source-line-no">5851</span><span id="line-5851"> return CONF;</span>
<span class="source-line-no">5852</span><span id="line-5852"> }</span>
<span class="source-line-no">5853</span><span id="line-5853"></span>
<span class="source-line-no">5854</span><span id="line-5854"> /**</span>
<span class="source-line-no">5855</span><span id="line-5855"> * @return A region on which you must call {@link HBaseTestingUtil#closeRegionAndWAL(HRegion)}</span>
<span class="source-line-no">5856</span><span id="line-5856"> * when done.</span>
<span class="source-line-no">5857</span><span id="line-5857"> */</span>
<span class="source-line-no">5858</span><span id="line-5858"> protected HRegion initHRegion(TableName tableName, String callingMethod, Configuration conf,</span>
<span class="source-line-no">5859</span><span id="line-5859"> byte[]... families) throws IOException {</span>
<span class="source-line-no">5860</span><span id="line-5860"> return initHRegion(tableName, callingMethod, conf, false, families);</span>
<span class="source-line-no">5861</span><span id="line-5861"> }</span>
<span class="source-line-no">5862</span><span id="line-5862"></span>
<span class="source-line-no">5863</span><span id="line-5863"> /**</span>
<span class="source-line-no">5864</span><span id="line-5864"> * @return A region on which you must call {@link HBaseTestingUtil#closeRegionAndWAL(HRegion)}</span>
<span class="source-line-no">5865</span><span id="line-5865"> * when done.</span>
<span class="source-line-no">5866</span><span id="line-5866"> */</span>
<span class="source-line-no">5867</span><span id="line-5867"> private HRegion initHRegion(TableName tableName, String callingMethod, Configuration conf,</span>
<span class="source-line-no">5868</span><span id="line-5868"> boolean isReadOnly, byte[]... families) throws IOException {</span>
<span class="source-line-no">5869</span><span id="line-5869"> return initHRegion(tableName, null, null, callingMethod, conf, isReadOnly, families);</span>
<span class="source-line-no">5870</span><span id="line-5870"> }</span>
<span class="source-line-no">5871</span><span id="line-5871"></span>
<span class="source-line-no">5872</span><span id="line-5872"> private HRegion initHRegion(TableName tableName, byte[] startKey, byte[] stopKey,</span>
<span class="source-line-no">5873</span><span id="line-5873"> String callingMethod, Configuration conf, boolean isReadOnly, byte[]... families)</span>
<span class="source-line-no">5874</span><span id="line-5874"> throws IOException {</span>
<span class="source-line-no">5875</span><span id="line-5875"> Path logDir = TEST_UTIL.getDataTestDirOnTestFS(callingMethod + ".log");</span>
<span class="source-line-no">5876</span><span id="line-5876"> RegionInfo hri =</span>
<span class="source-line-no">5877</span><span id="line-5877"> RegionInfoBuilder.newBuilder(tableName).setStartKey(startKey).setEndKey(stopKey).build();</span>
<span class="source-line-no">5878</span><span id="line-5878"> final WAL wal = HBaseTestingUtil.createWal(conf, logDir, hri);</span>
<span class="source-line-no">5879</span><span id="line-5879"> return initHRegion(tableName, startKey, stopKey, conf, isReadOnly, Durability.SYNC_WAL, wal,</span>
<span class="source-line-no">5880</span><span id="line-5880"> families);</span>
<span class="source-line-no">5881</span><span id="line-5881"> }</span>
<span class="source-line-no">5882</span><span id="line-5882"></span>
<span class="source-line-no">5883</span><span id="line-5883"> /**</span>
<span class="source-line-no">5884</span><span id="line-5884"> * @return A region on which you must call {@link HBaseTestingUtil#closeRegionAndWAL(HRegion)}</span>
<span class="source-line-no">5885</span><span id="line-5885"> * when done.</span>
<span class="source-line-no">5886</span><span id="line-5886"> */</span>
<span class="source-line-no">5887</span><span id="line-5887"> protected HRegion initHRegion(TableName tableName, byte[] startKey, byte[] stopKey,</span>
<span class="source-line-no">5888</span><span id="line-5888"> Configuration conf, boolean isReadOnly, Durability durability, WAL wal, byte[]... families)</span>
<span class="source-line-no">5889</span><span id="line-5889"> throws IOException {</span>
<span class="source-line-no">5890</span><span id="line-5890"> ChunkCreator.initialize(MemStoreLAB.CHUNK_SIZE_DEFAULT, false, 0, 0, 0, null,</span>
<span class="source-line-no">5891</span><span id="line-5891"> MemStoreLAB.INDEX_CHUNK_SIZE_PERCENTAGE_DEFAULT);</span>
<span class="source-line-no">5892</span><span id="line-5892"> return TEST_UTIL.createLocalHRegion(tableName, startKey, stopKey, conf, isReadOnly, durability,</span>
<span class="source-line-no">5893</span><span id="line-5893"> wal, families);</span>
<span class="source-line-no">5894</span><span id="line-5894"> }</span>
<span class="source-line-no">5895</span><span id="line-5895"></span>
<span class="source-line-no">5896</span><span id="line-5896"> /**</span>
<span class="source-line-no">5897</span><span id="line-5897"> * Assert that the passed in Cell has expected contents for the specified row, column &amp; timestamp.</span>
<span class="source-line-no">5898</span><span id="line-5898"> */</span>
<span class="source-line-no">5899</span><span id="line-5899"> private void checkOneCell(Cell kv, byte[] cf, int rowIdx, int colIdx, long ts) {</span>
<span class="source-line-no">5900</span><span id="line-5900"> String ctx = "rowIdx=" + rowIdx + "; colIdx=" + colIdx + "; ts=" + ts;</span>
<span class="source-line-no">5901</span><span id="line-5901"> assertEquals("Row mismatch which checking: " + ctx, "row:" + rowIdx,</span>
<span class="source-line-no">5902</span><span id="line-5902"> Bytes.toString(CellUtil.cloneRow(kv)));</span>
<span class="source-line-no">5903</span><span id="line-5903"> assertEquals("ColumnFamily mismatch while checking: " + ctx, Bytes.toString(cf),</span>
<span class="source-line-no">5904</span><span id="line-5904"> Bytes.toString(CellUtil.cloneFamily(kv)));</span>
<span class="source-line-no">5905</span><span id="line-5905"> assertEquals("Column qualifier mismatch while checking: " + ctx, "column:" + colIdx,</span>
<span class="source-line-no">5906</span><span id="line-5906"> Bytes.toString(CellUtil.cloneQualifier(kv)));</span>
<span class="source-line-no">5907</span><span id="line-5907"> assertEquals("Timestamp mismatch while checking: " + ctx, ts, kv.getTimestamp());</span>
<span class="source-line-no">5908</span><span id="line-5908"> assertEquals("Value mismatch while checking: " + ctx, "value-version-" + ts,</span>
<span class="source-line-no">5909</span><span id="line-5909"> Bytes.toString(CellUtil.cloneValue(kv)));</span>
<span class="source-line-no">5910</span><span id="line-5910"> }</span>
<span class="source-line-no">5911</span><span id="line-5911"></span>
<span class="source-line-no">5912</span><span id="line-5912"> @Test</span>
<span class="source-line-no">5913</span><span id="line-5913"> public void testReverseScanner_FromMemStore_SingleCF_Normal() throws IOException {</span>
<span class="source-line-no">5914</span><span id="line-5914"> byte[] rowC = Bytes.toBytes("rowC");</span>
<span class="source-line-no">5915</span><span id="line-5915"> byte[] rowA = Bytes.toBytes("rowA");</span>
<span class="source-line-no">5916</span><span id="line-5916"> byte[] rowB = Bytes.toBytes("rowB");</span>
<span class="source-line-no">5917</span><span id="line-5917"> byte[] cf = Bytes.toBytes("CF");</span>
<span class="source-line-no">5918</span><span id="line-5918"> byte[][] families = { cf };</span>
<span class="source-line-no">5919</span><span id="line-5919"> byte[] col = Bytes.toBytes("C");</span>
<span class="source-line-no">5920</span><span id="line-5920"> long ts = 1;</span>
<span class="source-line-no">5921</span><span id="line-5921"> this.region = initHRegion(tableName, method, families);</span>
<span class="source-line-no">5922</span><span id="line-5922"> KeyValue kv1 = new KeyValue(rowC, cf, col, ts, KeyValue.Type.Put, null);</span>
<span class="source-line-no">5923</span><span id="line-5923"> KeyValue kv11 = new KeyValue(rowC, cf, col, ts + 1, KeyValue.Type.Put, null);</span>
<span class="source-line-no">5924</span><span id="line-5924"> KeyValue kv2 = new KeyValue(rowA, cf, col, ts, KeyValue.Type.Put, null);</span>
<span class="source-line-no">5925</span><span id="line-5925"> KeyValue kv3 = new KeyValue(rowB, cf, col, ts, KeyValue.Type.Put, null);</span>
<span class="source-line-no">5926</span><span id="line-5926"> Put put = null;</span>
<span class="source-line-no">5927</span><span id="line-5927"> put = new Put(rowC);</span>
<span class="source-line-no">5928</span><span id="line-5928"> put.add(kv1);</span>
<span class="source-line-no">5929</span><span id="line-5929"> put.add(kv11);</span>
<span class="source-line-no">5930</span><span id="line-5930"> region.put(put);</span>
<span class="source-line-no">5931</span><span id="line-5931"> put = new Put(rowA);</span>
<span class="source-line-no">5932</span><span id="line-5932"> put.add(kv2);</span>
<span class="source-line-no">5933</span><span id="line-5933"> region.put(put);</span>
<span class="source-line-no">5934</span><span id="line-5934"> put = new Put(rowB);</span>
<span class="source-line-no">5935</span><span id="line-5935"> put.add(kv3);</span>
<span class="source-line-no">5936</span><span id="line-5936"> region.put(put);</span>
<span class="source-line-no">5937</span><span id="line-5937"></span>
<span class="source-line-no">5938</span><span id="line-5938"> Scan scan = new Scan().withStartRow(rowC);</span>
<span class="source-line-no">5939</span><span id="line-5939"> scan.readVersions(5);</span>
<span class="source-line-no">5940</span><span id="line-5940"> scan.setReversed(true);</span>
<span class="source-line-no">5941</span><span id="line-5941"> try (InternalScanner scanner = region.getScanner(scan)) {</span>
<span class="source-line-no">5942</span><span id="line-5942"> List&lt;Cell&gt; currRow = new ArrayList&lt;&gt;();</span>
<span class="source-line-no">5943</span><span id="line-5943"> boolean hasNext = scanner.next(currRow);</span>
<span class="source-line-no">5944</span><span id="line-5944"> assertEquals(2, currRow.size());</span>
<span class="source-line-no">5945</span><span id="line-5945"> assertTrue(Bytes.equals(currRow.get(0).getRowArray(), currRow.get(0).getRowOffset(),</span>
<span class="source-line-no">5946</span><span id="line-5946"> currRow.get(0).getRowLength(), rowC, 0, rowC.length));</span>
<span class="source-line-no">5947</span><span id="line-5947"> assertTrue(hasNext);</span>
<span class="source-line-no">5948</span><span id="line-5948"> currRow.clear();</span>
<span class="source-line-no">5949</span><span id="line-5949"> hasNext = scanner.next(currRow);</span>
<span class="source-line-no">5950</span><span id="line-5950"> assertEquals(1, currRow.size());</span>
<span class="source-line-no">5951</span><span id="line-5951"> assertTrue(Bytes.equals(currRow.get(0).getRowArray(), currRow.get(0).getRowOffset(),</span>
<span class="source-line-no">5952</span><span id="line-5952"> currRow.get(0).getRowLength(), rowB, 0, rowB.length));</span>
<span class="source-line-no">5953</span><span id="line-5953"> assertTrue(hasNext);</span>
<span class="source-line-no">5954</span><span id="line-5954"> currRow.clear();</span>
<span class="source-line-no">5955</span><span id="line-5955"> hasNext = scanner.next(currRow);</span>
<span class="source-line-no">5956</span><span id="line-5956"> assertEquals(1, currRow.size());</span>
<span class="source-line-no">5957</span><span id="line-5957"> assertTrue(Bytes.equals(currRow.get(0).getRowArray(), currRow.get(0).getRowOffset(),</span>
<span class="source-line-no">5958</span><span id="line-5958"> currRow.get(0).getRowLength(), rowA, 0, rowA.length));</span>
<span class="source-line-no">5959</span><span id="line-5959"> assertFalse(hasNext);</span>
<span class="source-line-no">5960</span><span id="line-5960"> }</span>
<span class="source-line-no">5961</span><span id="line-5961"> }</span>
<span class="source-line-no">5962</span><span id="line-5962"></span>
<span class="source-line-no">5963</span><span id="line-5963"> @Test</span>
<span class="source-line-no">5964</span><span id="line-5964"> public void testReverseScanner_FromMemStore_SingleCF_LargerKey() throws IOException {</span>
<span class="source-line-no">5965</span><span id="line-5965"> byte[] rowC = Bytes.toBytes("rowC");</span>
<span class="source-line-no">5966</span><span id="line-5966"> byte[] rowA = Bytes.toBytes("rowA");</span>
<span class="source-line-no">5967</span><span id="line-5967"> byte[] rowB = Bytes.toBytes("rowB");</span>
<span class="source-line-no">5968</span><span id="line-5968"> byte[] rowD = Bytes.toBytes("rowD");</span>
<span class="source-line-no">5969</span><span id="line-5969"> byte[] cf = Bytes.toBytes("CF");</span>
<span class="source-line-no">5970</span><span id="line-5970"> byte[][] families = { cf };</span>
<span class="source-line-no">5971</span><span id="line-5971"> byte[] col = Bytes.toBytes("C");</span>
<span class="source-line-no">5972</span><span id="line-5972"> long ts = 1;</span>
<span class="source-line-no">5973</span><span id="line-5973"> this.region = initHRegion(tableName, method, families);</span>
<span class="source-line-no">5974</span><span id="line-5974"> KeyValue kv1 = new KeyValue(rowC, cf, col, ts, KeyValue.Type.Put, null);</span>
<span class="source-line-no">5975</span><span id="line-5975"> KeyValue kv11 = new KeyValue(rowC, cf, col, ts + 1, KeyValue.Type.Put, null);</span>
<span class="source-line-no">5976</span><span id="line-5976"> KeyValue kv2 = new KeyValue(rowA, cf, col, ts, KeyValue.Type.Put, null);</span>
<span class="source-line-no">5977</span><span id="line-5977"> KeyValue kv3 = new KeyValue(rowB, cf, col, ts, KeyValue.Type.Put, null);</span>
<span class="source-line-no">5978</span><span id="line-5978"> Put put = null;</span>
<span class="source-line-no">5979</span><span id="line-5979"> put = new Put(rowC);</span>
<span class="source-line-no">5980</span><span id="line-5980"> put.add(kv1);</span>
<span class="source-line-no">5981</span><span id="line-5981"> put.add(kv11);</span>
<span class="source-line-no">5982</span><span id="line-5982"> region.put(put);</span>
<span class="source-line-no">5983</span><span id="line-5983"> put = new Put(rowA);</span>
<span class="source-line-no">5984</span><span id="line-5984"> put.add(kv2);</span>
<span class="source-line-no">5985</span><span id="line-5985"> region.put(put);</span>
<span class="source-line-no">5986</span><span id="line-5986"> put = new Put(rowB);</span>
<span class="source-line-no">5987</span><span id="line-5987"> put.add(kv3);</span>
<span class="source-line-no">5988</span><span id="line-5988"> region.put(put);</span>
<span class="source-line-no">5989</span><span id="line-5989"></span>
<span class="source-line-no">5990</span><span id="line-5990"> Scan scan = new Scan().withStartRow(rowD);</span>
<span class="source-line-no">5991</span><span id="line-5991"> List&lt;Cell&gt; currRow = new ArrayList&lt;&gt;();</span>
<span class="source-line-no">5992</span><span id="line-5992"> scan.setReversed(true);</span>
<span class="source-line-no">5993</span><span id="line-5993"> scan.readVersions(5);</span>
<span class="source-line-no">5994</span><span id="line-5994"> try (InternalScanner scanner = region.getScanner(scan)) {</span>
<span class="source-line-no">5995</span><span id="line-5995"> boolean hasNext = scanner.next(currRow);</span>
<span class="source-line-no">5996</span><span id="line-5996"> assertEquals(2, currRow.size());</span>
<span class="source-line-no">5997</span><span id="line-5997"> assertTrue(Bytes.equals(currRow.get(0).getRowArray(), currRow.get(0).getRowOffset(),</span>
<span class="source-line-no">5998</span><span id="line-5998"> currRow.get(0).getRowLength(), rowC, 0, rowC.length));</span>
<span class="source-line-no">5999</span><span id="line-5999"> assertTrue(hasNext);</span>
<span class="source-line-no">6000</span><span id="line-6000"> currRow.clear();</span>
<span class="source-line-no">6001</span><span id="line-6001"> hasNext = scanner.next(currRow);</span>
<span class="source-line-no">6002</span><span id="line-6002"> assertEquals(1, currRow.size());</span>
<span class="source-line-no">6003</span><span id="line-6003"> assertTrue(Bytes.equals(currRow.get(0).getRowArray(), currRow.get(0).getRowOffset(),</span>
<span class="source-line-no">6004</span><span id="line-6004"> currRow.get(0).getRowLength(), rowB, 0, rowB.length));</span>
<span class="source-line-no">6005</span><span id="line-6005"> assertTrue(hasNext);</span>
<span class="source-line-no">6006</span><span id="line-6006"> currRow.clear();</span>
<span class="source-line-no">6007</span><span id="line-6007"> hasNext = scanner.next(currRow);</span>
<span class="source-line-no">6008</span><span id="line-6008"> assertEquals(1, currRow.size());</span>
<span class="source-line-no">6009</span><span id="line-6009"> assertTrue(Bytes.equals(currRow.get(0).getRowArray(), currRow.get(0).getRowOffset(),</span>
<span class="source-line-no">6010</span><span id="line-6010"> currRow.get(0).getRowLength(), rowA, 0, rowA.length));</span>
<span class="source-line-no">6011</span><span id="line-6011"> assertFalse(hasNext);</span>
<span class="source-line-no">6012</span><span id="line-6012"> }</span>
<span class="source-line-no">6013</span><span id="line-6013"> }</span>
<span class="source-line-no">6014</span><span id="line-6014"></span>
<span class="source-line-no">6015</span><span id="line-6015"> @Test</span>
<span class="source-line-no">6016</span><span id="line-6016"> public void testReverseScanner_FromMemStore_SingleCF_FullScan() throws IOException {</span>
<span class="source-line-no">6017</span><span id="line-6017"> byte[] rowC = Bytes.toBytes("rowC");</span>
<span class="source-line-no">6018</span><span id="line-6018"> byte[] rowA = Bytes.toBytes("rowA");</span>
<span class="source-line-no">6019</span><span id="line-6019"> byte[] rowB = Bytes.toBytes("rowB");</span>
<span class="source-line-no">6020</span><span id="line-6020"> byte[] cf = Bytes.toBytes("CF");</span>
<span class="source-line-no">6021</span><span id="line-6021"> byte[][] families = { cf };</span>
<span class="source-line-no">6022</span><span id="line-6022"> byte[] col = Bytes.toBytes("C");</span>
<span class="source-line-no">6023</span><span id="line-6023"> long ts = 1;</span>
<span class="source-line-no">6024</span><span id="line-6024"> this.region = initHRegion(tableName, method, families);</span>
<span class="source-line-no">6025</span><span id="line-6025"> KeyValue kv1 = new KeyValue(rowC, cf, col, ts, KeyValue.Type.Put, null);</span>
<span class="source-line-no">6026</span><span id="line-6026"> KeyValue kv11 = new KeyValue(rowC, cf, col, ts + 1, KeyValue.Type.Put, null);</span>
<span class="source-line-no">6027</span><span id="line-6027"> KeyValue kv2 = new KeyValue(rowA, cf, col, ts, KeyValue.Type.Put, null);</span>
<span class="source-line-no">6028</span><span id="line-6028"> KeyValue kv3 = new KeyValue(rowB, cf, col, ts, KeyValue.Type.Put, null);</span>
<span class="source-line-no">6029</span><span id="line-6029"> Put put = null;</span>
<span class="source-line-no">6030</span><span id="line-6030"> put = new Put(rowC);</span>
<span class="source-line-no">6031</span><span id="line-6031"> put.add(kv1);</span>
<span class="source-line-no">6032</span><span id="line-6032"> put.add(kv11);</span>
<span class="source-line-no">6033</span><span id="line-6033"> region.put(put);</span>
<span class="source-line-no">6034</span><span id="line-6034"> put = new Put(rowA);</span>
<span class="source-line-no">6035</span><span id="line-6035"> put.add(kv2);</span>
<span class="source-line-no">6036</span><span id="line-6036"> region.put(put);</span>
<span class="source-line-no">6037</span><span id="line-6037"> put = new Put(rowB);</span>
<span class="source-line-no">6038</span><span id="line-6038"> put.add(kv3);</span>
<span class="source-line-no">6039</span><span id="line-6039"> region.put(put);</span>
<span class="source-line-no">6040</span><span id="line-6040"> Scan scan = new Scan();</span>
<span class="source-line-no">6041</span><span id="line-6041"> List&lt;Cell&gt; currRow = new ArrayList&lt;&gt;();</span>
<span class="source-line-no">6042</span><span id="line-6042"> scan.setReversed(true);</span>
<span class="source-line-no">6043</span><span id="line-6043"> try (InternalScanner scanner = region.getScanner(scan)) {</span>
<span class="source-line-no">6044</span><span id="line-6044"> boolean hasNext = scanner.next(currRow);</span>
<span class="source-line-no">6045</span><span id="line-6045"> assertEquals(1, currRow.size());</span>
<span class="source-line-no">6046</span><span id="line-6046"> assertTrue(Bytes.equals(currRow.get(0).getRowArray(), currRow.get(0).getRowOffset(),</span>
<span class="source-line-no">6047</span><span id="line-6047"> currRow.get(0).getRowLength(), rowC, 0, rowC.length));</span>
<span class="source-line-no">6048</span><span id="line-6048"> assertTrue(hasNext);</span>
<span class="source-line-no">6049</span><span id="line-6049"> currRow.clear();</span>
<span class="source-line-no">6050</span><span id="line-6050"> hasNext = scanner.next(currRow);</span>
<span class="source-line-no">6051</span><span id="line-6051"> assertEquals(1, currRow.size());</span>
<span class="source-line-no">6052</span><span id="line-6052"> assertTrue(Bytes.equals(currRow.get(0).getRowArray(), currRow.get(0).getRowOffset(),</span>
<span class="source-line-no">6053</span><span id="line-6053"> currRow.get(0).getRowLength(), rowB, 0, rowB.length));</span>
<span class="source-line-no">6054</span><span id="line-6054"> assertTrue(hasNext);</span>
<span class="source-line-no">6055</span><span id="line-6055"> currRow.clear();</span>
<span class="source-line-no">6056</span><span id="line-6056"> hasNext = scanner.next(currRow);</span>
<span class="source-line-no">6057</span><span id="line-6057"> assertEquals(1, currRow.size());</span>
<span class="source-line-no">6058</span><span id="line-6058"> assertTrue(Bytes.equals(currRow.get(0).getRowArray(), currRow.get(0).getRowOffset(),</span>
<span class="source-line-no">6059</span><span id="line-6059"> currRow.get(0).getRowLength(), rowA, 0, rowA.length));</span>
<span class="source-line-no">6060</span><span id="line-6060"> assertFalse(hasNext);</span>
<span class="source-line-no">6061</span><span id="line-6061"> }</span>
<span class="source-line-no">6062</span><span id="line-6062"> }</span>
<span class="source-line-no">6063</span><span id="line-6063"></span>
<span class="source-line-no">6064</span><span id="line-6064"> @Test</span>
<span class="source-line-no">6065</span><span id="line-6065"> public void testReverseScanner_moreRowsMayExistAfter() throws IOException {</span>
<span class="source-line-no">6066</span><span id="line-6066"> // case for "INCLUDE_AND_SEEK_NEXT_ROW &amp; SEEK_NEXT_ROW" endless loop</span>
<span class="source-line-no">6067</span><span id="line-6067"> byte[] rowA = Bytes.toBytes("rowA");</span>
<span class="source-line-no">6068</span><span id="line-6068"> byte[] rowB = Bytes.toBytes("rowB");</span>
<span class="source-line-no">6069</span><span id="line-6069"> byte[] rowC = Bytes.toBytes("rowC");</span>
<span class="source-line-no">6070</span><span id="line-6070"> byte[] rowD = Bytes.toBytes("rowD");</span>
<span class="source-line-no">6071</span><span id="line-6071"> byte[] rowE = Bytes.toBytes("rowE");</span>
<span class="source-line-no">6072</span><span id="line-6072"> byte[] cf = Bytes.toBytes("CF");</span>
<span class="source-line-no">6073</span><span id="line-6073"> byte[][] families = { cf };</span>
<span class="source-line-no">6074</span><span id="line-6074"> byte[] col1 = Bytes.toBytes("col1");</span>
<span class="source-line-no">6075</span><span id="line-6075"> byte[] col2 = Bytes.toBytes("col2");</span>
<span class="source-line-no">6076</span><span id="line-6076"> long ts = 1;</span>
<span class="source-line-no">6077</span><span id="line-6077"> this.region = initHRegion(tableName, method, families);</span>
<span class="source-line-no">6078</span><span id="line-6078"> KeyValue kv1 = new KeyValue(rowA, cf, col1, ts, KeyValue.Type.Put, null);</span>
<span class="source-line-no">6079</span><span id="line-6079"> KeyValue kv2 = new KeyValue(rowB, cf, col1, ts, KeyValue.Type.Put, null);</span>
<span class="source-line-no">6080</span><span id="line-6080"> KeyValue kv3 = new KeyValue(rowC, cf, col1, ts, KeyValue.Type.Put, null);</span>
<span class="source-line-no">6081</span><span id="line-6081"> KeyValue kv4_1 = new KeyValue(rowD, cf, col1, ts, KeyValue.Type.Put, null);</span>
<span class="source-line-no">6082</span><span id="line-6082"> KeyValue kv4_2 = new KeyValue(rowD, cf, col2, ts, KeyValue.Type.Put, null);</span>
<span class="source-line-no">6083</span><span id="line-6083"> KeyValue kv5 = new KeyValue(rowE, cf, col1, ts, KeyValue.Type.Put, null);</span>
<span class="source-line-no">6084</span><span id="line-6084"> Put put = null;</span>
<span class="source-line-no">6085</span><span id="line-6085"> put = new Put(rowA);</span>
<span class="source-line-no">6086</span><span id="line-6086"> put.add(kv1);</span>
<span class="source-line-no">6087</span><span id="line-6087"> region.put(put);</span>
<span class="source-line-no">6088</span><span id="line-6088"> put = new Put(rowB);</span>
<span class="source-line-no">6089</span><span id="line-6089"> put.add(kv2);</span>
<span class="source-line-no">6090</span><span id="line-6090"> region.put(put);</span>
<span class="source-line-no">6091</span><span id="line-6091"> put = new Put(rowC);</span>
<span class="source-line-no">6092</span><span id="line-6092"> put.add(kv3);</span>
<span class="source-line-no">6093</span><span id="line-6093"> region.put(put);</span>
<span class="source-line-no">6094</span><span id="line-6094"> put = new Put(rowD);</span>
<span class="source-line-no">6095</span><span id="line-6095"> put.add(kv4_1);</span>
<span class="source-line-no">6096</span><span id="line-6096"> region.put(put);</span>
<span class="source-line-no">6097</span><span id="line-6097"> put = new Put(rowD);</span>
<span class="source-line-no">6098</span><span id="line-6098"> put.add(kv4_2);</span>
<span class="source-line-no">6099</span><span id="line-6099"> region.put(put);</span>
<span class="source-line-no">6100</span><span id="line-6100"> put = new Put(rowE);</span>
<span class="source-line-no">6101</span><span id="line-6101"> put.add(kv5);</span>
<span class="source-line-no">6102</span><span id="line-6102"> region.put(put);</span>
<span class="source-line-no">6103</span><span id="line-6103"> region.flush(true);</span>
<span class="source-line-no">6104</span><span id="line-6104"> Scan scan = new Scan().withStartRow(rowD).withStopRow(rowA);</span>
<span class="source-line-no">6105</span><span id="line-6105"> scan.addColumn(families[0], col1);</span>
<span class="source-line-no">6106</span><span id="line-6106"> scan.setReversed(true);</span>
<span class="source-line-no">6107</span><span id="line-6107"> List&lt;Cell&gt; currRow = new ArrayList&lt;&gt;();</span>
<span class="source-line-no">6108</span><span id="line-6108"> try (InternalScanner scanner = region.getScanner(scan)) {</span>
<span class="source-line-no">6109</span><span id="line-6109"> boolean hasNext = scanner.next(currRow);</span>
<span class="source-line-no">6110</span><span id="line-6110"> assertEquals(1, currRow.size());</span>
<span class="source-line-no">6111</span><span id="line-6111"> assertTrue(Bytes.equals(currRow.get(0).getRowArray(), currRow.get(0).getRowOffset(),</span>
<span class="source-line-no">6112</span><span id="line-6112"> currRow.get(0).getRowLength(), rowD, 0, rowD.length));</span>
<span class="source-line-no">6113</span><span id="line-6113"> assertTrue(hasNext);</span>
<span class="source-line-no">6114</span><span id="line-6114"> currRow.clear();</span>
<span class="source-line-no">6115</span><span id="line-6115"> hasNext = scanner.next(currRow);</span>
<span class="source-line-no">6116</span><span id="line-6116"> assertEquals(1, currRow.size());</span>
<span class="source-line-no">6117</span><span id="line-6117"> assertTrue(Bytes.equals(currRow.get(0).getRowArray(), currRow.get(0).getRowOffset(),</span>
<span class="source-line-no">6118</span><span id="line-6118"> currRow.get(0).getRowLength(), rowC, 0, rowC.length));</span>
<span class="source-line-no">6119</span><span id="line-6119"> assertTrue(hasNext);</span>
<span class="source-line-no">6120</span><span id="line-6120"> currRow.clear();</span>
<span class="source-line-no">6121</span><span id="line-6121"> hasNext = scanner.next(currRow);</span>
<span class="source-line-no">6122</span><span id="line-6122"> assertEquals(1, currRow.size());</span>
<span class="source-line-no">6123</span><span id="line-6123"> assertTrue(Bytes.equals(currRow.get(0).getRowArray(), currRow.get(0).getRowOffset(),</span>
<span class="source-line-no">6124</span><span id="line-6124"> currRow.get(0).getRowLength(), rowB, 0, rowB.length));</span>
<span class="source-line-no">6125</span><span id="line-6125"> assertFalse(hasNext);</span>
<span class="source-line-no">6126</span><span id="line-6126"> }</span>
<span class="source-line-no">6127</span><span id="line-6127"></span>
<span class="source-line-no">6128</span><span id="line-6128"> scan = new Scan().withStartRow(rowD).withStopRow(rowA);</span>
<span class="source-line-no">6129</span><span id="line-6129"> scan.addColumn(families[0], col2);</span>
<span class="source-line-no">6130</span><span id="line-6130"> scan.setReversed(true);</span>
<span class="source-line-no">6131</span><span id="line-6131"> currRow.clear();</span>
<span class="source-line-no">6132</span><span id="line-6132"> try (InternalScanner scanner = region.getScanner(scan)) {</span>
<span class="source-line-no">6133</span><span id="line-6133"> boolean hasNext = scanner.next(currRow);</span>
<span class="source-line-no">6134</span><span id="line-6134"> assertEquals(1, currRow.size());</span>
<span class="source-line-no">6135</span><span id="line-6135"> assertTrue(Bytes.equals(currRow.get(0).getRowArray(), currRow.get(0).getRowOffset(),</span>
<span class="source-line-no">6136</span><span id="line-6136"> currRow.get(0).getRowLength(), rowD, 0, rowD.length));</span>
<span class="source-line-no">6137</span><span id="line-6137"> assertTrue(hasNext);</span>
<span class="source-line-no">6138</span><span id="line-6138"> }</span>
<span class="source-line-no">6139</span><span id="line-6139"> }</span>
<span class="source-line-no">6140</span><span id="line-6140"></span>
<span class="source-line-no">6141</span><span id="line-6141"> @Test</span>
<span class="source-line-no">6142</span><span id="line-6142"> public void testReverseScanner_smaller_blocksize() throws IOException {</span>
<span class="source-line-no">6143</span><span id="line-6143"> // case to ensure no conflict with HFile index optimization</span>
<span class="source-line-no">6144</span><span id="line-6144"> byte[] rowA = Bytes.toBytes("rowA");</span>
<span class="source-line-no">6145</span><span id="line-6145"> byte[] rowB = Bytes.toBytes("rowB");</span>
<span class="source-line-no">6146</span><span id="line-6146"> byte[] rowC = Bytes.toBytes("rowC");</span>
<span class="source-line-no">6147</span><span id="line-6147"> byte[] rowD = Bytes.toBytes("rowD");</span>
<span class="source-line-no">6148</span><span id="line-6148"> byte[] rowE = Bytes.toBytes("rowE");</span>
<span class="source-line-no">6149</span><span id="line-6149"> byte[] cf = Bytes.toBytes("CF");</span>
<span class="source-line-no">6150</span><span id="line-6150"> byte[][] families = { cf };</span>
<span class="source-line-no">6151</span><span id="line-6151"> byte[] col1 = Bytes.toBytes("col1");</span>
<span class="source-line-no">6152</span><span id="line-6152"> byte[] col2 = Bytes.toBytes("col2");</span>
<span class="source-line-no">6153</span><span id="line-6153"> long ts = 1;</span>
<span class="source-line-no">6154</span><span id="line-6154"> Configuration conf = new Configuration(CONF);</span>
<span class="source-line-no">6155</span><span id="line-6155"> conf.setInt("test.block.size", 1);</span>
<span class="source-line-no">6156</span><span id="line-6156"> this.region = initHRegion(tableName, method, conf, families);</span>
<span class="source-line-no">6157</span><span id="line-6157"> KeyValue kv1 = new KeyValue(rowA, cf, col1, ts, KeyValue.Type.Put, null);</span>
<span class="source-line-no">6158</span><span id="line-6158"> KeyValue kv2 = new KeyValue(rowB, cf, col1, ts, KeyValue.Type.Put, null);</span>
<span class="source-line-no">6159</span><span id="line-6159"> KeyValue kv3 = new KeyValue(rowC, cf, col1, ts, KeyValue.Type.Put, null);</span>
<span class="source-line-no">6160</span><span id="line-6160"> KeyValue kv4_1 = new KeyValue(rowD, cf, col1, ts, KeyValue.Type.Put, null);</span>
<span class="source-line-no">6161</span><span id="line-6161"> KeyValue kv4_2 = new KeyValue(rowD, cf, col2, ts, KeyValue.Type.Put, null);</span>
<span class="source-line-no">6162</span><span id="line-6162"> KeyValue kv5 = new KeyValue(rowE, cf, col1, ts, KeyValue.Type.Put, null);</span>
<span class="source-line-no">6163</span><span id="line-6163"> Put put = null;</span>
<span class="source-line-no">6164</span><span id="line-6164"> put = new Put(rowA);</span>
<span class="source-line-no">6165</span><span id="line-6165"> put.add(kv1);</span>
<span class="source-line-no">6166</span><span id="line-6166"> region.put(put);</span>
<span class="source-line-no">6167</span><span id="line-6167"> put = new Put(rowB);</span>
<span class="source-line-no">6168</span><span id="line-6168"> put.add(kv2);</span>
<span class="source-line-no">6169</span><span id="line-6169"> region.put(put);</span>
<span class="source-line-no">6170</span><span id="line-6170"> put = new Put(rowC);</span>
<span class="source-line-no">6171</span><span id="line-6171"> put.add(kv3);</span>
<span class="source-line-no">6172</span><span id="line-6172"> region.put(put);</span>
<span class="source-line-no">6173</span><span id="line-6173"> put = new Put(rowD);</span>
<span class="source-line-no">6174</span><span id="line-6174"> put.add(kv4_1);</span>
<span class="source-line-no">6175</span><span id="line-6175"> region.put(put);</span>
<span class="source-line-no">6176</span><span id="line-6176"> put = new Put(rowD);</span>
<span class="source-line-no">6177</span><span id="line-6177"> put.add(kv4_2);</span>
<span class="source-line-no">6178</span><span id="line-6178"> region.put(put);</span>
<span class="source-line-no">6179</span><span id="line-6179"> put = new Put(rowE);</span>
<span class="source-line-no">6180</span><span id="line-6180"> put.add(kv5);</span>
<span class="source-line-no">6181</span><span id="line-6181"> region.put(put);</span>
<span class="source-line-no">6182</span><span id="line-6182"> region.flush(true);</span>
<span class="source-line-no">6183</span><span id="line-6183"> Scan scan = new Scan().withStartRow(rowD).withStopRow(rowA);</span>
<span class="source-line-no">6184</span><span id="line-6184"> scan.addColumn(families[0], col1);</span>
<span class="source-line-no">6185</span><span id="line-6185"> scan.setReversed(true);</span>
<span class="source-line-no">6186</span><span id="line-6186"> List&lt;Cell&gt; currRow = new ArrayList&lt;&gt;();</span>
<span class="source-line-no">6187</span><span id="line-6187"> try (InternalScanner scanner = region.getScanner(scan)) {</span>
<span class="source-line-no">6188</span><span id="line-6188"> boolean hasNext = scanner.next(currRow);</span>
<span class="source-line-no">6189</span><span id="line-6189"> assertEquals(1, currRow.size());</span>
<span class="source-line-no">6190</span><span id="line-6190"> assertTrue(Bytes.equals(currRow.get(0).getRowArray(), currRow.get(0).getRowOffset(),</span>
<span class="source-line-no">6191</span><span id="line-6191"> currRow.get(0).getRowLength(), rowD, 0, rowD.length));</span>
<span class="source-line-no">6192</span><span id="line-6192"> assertTrue(hasNext);</span>
<span class="source-line-no">6193</span><span id="line-6193"> currRow.clear();</span>
<span class="source-line-no">6194</span><span id="line-6194"> hasNext = scanner.next(currRow);</span>
<span class="source-line-no">6195</span><span id="line-6195"> assertEquals(1, currRow.size());</span>
<span class="source-line-no">6196</span><span id="line-6196"> assertTrue(Bytes.equals(currRow.get(0).getRowArray(), currRow.get(0).getRowOffset(),</span>
<span class="source-line-no">6197</span><span id="line-6197"> currRow.get(0).getRowLength(), rowC, 0, rowC.length));</span>
<span class="source-line-no">6198</span><span id="line-6198"> assertTrue(hasNext);</span>
<span class="source-line-no">6199</span><span id="line-6199"> currRow.clear();</span>
<span class="source-line-no">6200</span><span id="line-6200"> hasNext = scanner.next(currRow);</span>
<span class="source-line-no">6201</span><span id="line-6201"> assertEquals(1, currRow.size());</span>
<span class="source-line-no">6202</span><span id="line-6202"> assertTrue(Bytes.equals(currRow.get(0).getRowArray(), currRow.get(0).getRowOffset(),</span>
<span class="source-line-no">6203</span><span id="line-6203"> currRow.get(0).getRowLength(), rowB, 0, rowB.length));</span>
<span class="source-line-no">6204</span><span id="line-6204"> assertFalse(hasNext);</span>
<span class="source-line-no">6205</span><span id="line-6205"> }</span>
<span class="source-line-no">6206</span><span id="line-6206"></span>
<span class="source-line-no">6207</span><span id="line-6207"> scan = new Scan().withStartRow(rowD).withStopRow(rowA);</span>
<span class="source-line-no">6208</span><span id="line-6208"> scan.addColumn(families[0], col2);</span>
<span class="source-line-no">6209</span><span id="line-6209"> scan.setReversed(true);</span>
<span class="source-line-no">6210</span><span id="line-6210"> currRow.clear();</span>
<span class="source-line-no">6211</span><span id="line-6211"> try (InternalScanner scanner = region.getScanner(scan)) {</span>
<span class="source-line-no">6212</span><span id="line-6212"> boolean hasNext = scanner.next(currRow);</span>
<span class="source-line-no">6213</span><span id="line-6213"> assertEquals(1, currRow.size());</span>
<span class="source-line-no">6214</span><span id="line-6214"> assertTrue(Bytes.equals(currRow.get(0).getRowArray(), currRow.get(0).getRowOffset(),</span>
<span class="source-line-no">6215</span><span id="line-6215"> currRow.get(0).getRowLength(), rowD, 0, rowD.length));</span>
<span class="source-line-no">6216</span><span id="line-6216"> assertTrue(hasNext);</span>
<span class="source-line-no">6217</span><span id="line-6217"> }</span>
<span class="source-line-no">6218</span><span id="line-6218"> }</span>
<span class="source-line-no">6219</span><span id="line-6219"></span>
<span class="source-line-no">6220</span><span id="line-6220"> @Test</span>
<span class="source-line-no">6221</span><span id="line-6221"> public void testReverseScanner_FromMemStoreAndHFiles_MultiCFs1() throws IOException {</span>
<span class="source-line-no">6222</span><span id="line-6222"> byte[] row0 = Bytes.toBytes("row0"); // 1 kv</span>
<span class="source-line-no">6223</span><span id="line-6223"> byte[] row1 = Bytes.toBytes("row1"); // 2 kv</span>
<span class="source-line-no">6224</span><span id="line-6224"> byte[] row2 = Bytes.toBytes("row2"); // 4 kv</span>
<span class="source-line-no">6225</span><span id="line-6225"> byte[] row3 = Bytes.toBytes("row3"); // 2 kv</span>
<span class="source-line-no">6226</span><span id="line-6226"> byte[] row4 = Bytes.toBytes("row4"); // 5 kv</span>
<span class="source-line-no">6227</span><span id="line-6227"> byte[] row5 = Bytes.toBytes("row5"); // 2 kv</span>
<span class="source-line-no">6228</span><span id="line-6228"> byte[] cf1 = Bytes.toBytes("CF1");</span>
<span class="source-line-no">6229</span><span id="line-6229"> byte[] cf2 = Bytes.toBytes("CF2");</span>
<span class="source-line-no">6230</span><span id="line-6230"> byte[] cf3 = Bytes.toBytes("CF3");</span>
<span class="source-line-no">6231</span><span id="line-6231"> byte[][] families = { cf1, cf2, cf3 };</span>
<span class="source-line-no">6232</span><span id="line-6232"> byte[] col = Bytes.toBytes("C");</span>
<span class="source-line-no">6233</span><span id="line-6233"> long ts = 1;</span>
<span class="source-line-no">6234</span><span id="line-6234"> Configuration conf = new Configuration(CONF);</span>
<span class="source-line-no">6235</span><span id="line-6235"> // disable compactions in this test.</span>
<span class="source-line-no">6236</span><span id="line-6236"> conf.setInt("hbase.hstore.compactionThreshold", 10000);</span>
<span class="source-line-no">6237</span><span id="line-6237"> this.region = initHRegion(tableName, method, conf, families);</span>
<span class="source-line-no">6238</span><span id="line-6238"> // kv naming style: kv(row number) totalKvCountInThisRow seq no</span>
<span class="source-line-no">6239</span><span id="line-6239"> KeyValue kv0_1_1 = new KeyValue(row0, cf1, col, ts, KeyValue.Type.Put, null);</span>
<span class="source-line-no">6240</span><span id="line-6240"> KeyValue kv1_2_1 = new KeyValue(row1, cf2, col, ts, KeyValue.Type.Put, null);</span>
<span class="source-line-no">6241</span><span id="line-6241"> KeyValue kv1_2_2 = new KeyValue(row1, cf1, col, ts + 1, KeyValue.Type.Put, null);</span>
<span class="source-line-no">6242</span><span id="line-6242"> KeyValue kv2_4_1 = new KeyValue(row2, cf2, col, ts, KeyValue.Type.Put, null);</span>
<span class="source-line-no">6243</span><span id="line-6243"> KeyValue kv2_4_2 = new KeyValue(row2, cf1, col, ts, KeyValue.Type.Put, null);</span>
<span class="source-line-no">6244</span><span id="line-6244"> KeyValue kv2_4_3 = new KeyValue(row2, cf3, col, ts, KeyValue.Type.Put, null);</span>
<span class="source-line-no">6245</span><span id="line-6245"> KeyValue kv2_4_4 = new KeyValue(row2, cf1, col, ts + 4, KeyValue.Type.Put, null);</span>
<span class="source-line-no">6246</span><span id="line-6246"> KeyValue kv3_2_1 = new KeyValue(row3, cf2, col, ts, KeyValue.Type.Put, null);</span>
<span class="source-line-no">6247</span><span id="line-6247"> KeyValue kv3_2_2 = new KeyValue(row3, cf1, col, ts + 4, KeyValue.Type.Put, null);</span>
<span class="source-line-no">6248</span><span id="line-6248"> KeyValue kv4_5_1 = new KeyValue(row4, cf1, col, ts, KeyValue.Type.Put, null);</span>
<span class="source-line-no">6249</span><span id="line-6249"> KeyValue kv4_5_2 = new KeyValue(row4, cf3, col, ts, KeyValue.Type.Put, null);</span>
<span class="source-line-no">6250</span><span id="line-6250"> KeyValue kv4_5_3 = new KeyValue(row4, cf3, col, ts + 5, KeyValue.Type.Put, null);</span>
<span class="source-line-no">6251</span><span id="line-6251"> KeyValue kv4_5_4 = new KeyValue(row4, cf2, col, ts, KeyValue.Type.Put, null);</span>
<span class="source-line-no">6252</span><span id="line-6252"> KeyValue kv4_5_5 = new KeyValue(row4, cf1, col, ts + 3, KeyValue.Type.Put, null);</span>
<span class="source-line-no">6253</span><span id="line-6253"> KeyValue kv5_2_1 = new KeyValue(row5, cf2, col, ts, KeyValue.Type.Put, null);</span>
<span class="source-line-no">6254</span><span id="line-6254"> KeyValue kv5_2_2 = new KeyValue(row5, cf3, col, ts, KeyValue.Type.Put, null);</span>
<span class="source-line-no">6255</span><span id="line-6255"> // hfiles(cf1/cf2) :"row1"(1 kv) / "row2"(1 kv) / "row4"(2 kv)</span>
<span class="source-line-no">6256</span><span id="line-6256"> Put put = null;</span>
<span class="source-line-no">6257</span><span id="line-6257"> put = new Put(row1);</span>
<span class="source-line-no">6258</span><span id="line-6258"> put.add(kv1_2_1);</span>
<span class="source-line-no">6259</span><span id="line-6259"> region.put(put);</span>
<span class="source-line-no">6260</span><span id="line-6260"> put = new Put(row2);</span>
<span class="source-line-no">6261</span><span id="line-6261"> put.add(kv2_4_1);</span>
<span class="source-line-no">6262</span><span id="line-6262"> region.put(put);</span>
<span class="source-line-no">6263</span><span id="line-6263"> put = new Put(row4);</span>
<span class="source-line-no">6264</span><span id="line-6264"> put.add(kv4_5_4);</span>
<span class="source-line-no">6265</span><span id="line-6265"> put.add(kv4_5_5);</span>
<span class="source-line-no">6266</span><span id="line-6266"> region.put(put);</span>
<span class="source-line-no">6267</span><span id="line-6267"> region.flush(true);</span>
<span class="source-line-no">6268</span><span id="line-6268"> // hfiles(cf1/cf3) : "row1" (1 kvs) / "row2" (1 kv) / "row4" (2 kv)</span>
<span class="source-line-no">6269</span><span id="line-6269"> put = new Put(row4);</span>
<span class="source-line-no">6270</span><span id="line-6270"> put.add(kv4_5_1);</span>
<span class="source-line-no">6271</span><span id="line-6271"> put.add(kv4_5_3);</span>
<span class="source-line-no">6272</span><span id="line-6272"> region.put(put);</span>
<span class="source-line-no">6273</span><span id="line-6273"> put = new Put(row1);</span>
<span class="source-line-no">6274</span><span id="line-6274"> put.add(kv1_2_2);</span>
<span class="source-line-no">6275</span><span id="line-6275"> region.put(put);</span>
<span class="source-line-no">6276</span><span id="line-6276"> put = new Put(row2);</span>
<span class="source-line-no">6277</span><span id="line-6277"> put.add(kv2_4_4);</span>
<span class="source-line-no">6278</span><span id="line-6278"> region.put(put);</span>
<span class="source-line-no">6279</span><span id="line-6279"> region.flush(true);</span>
<span class="source-line-no">6280</span><span id="line-6280"> // hfiles(cf1/cf3) : "row2"(2 kv) / "row3"(1 kvs) / "row4" (1 kv)</span>
<span class="source-line-no">6281</span><span id="line-6281"> put = new Put(row4);</span>
<span class="source-line-no">6282</span><span id="line-6282"> put.add(kv4_5_2);</span>
<span class="source-line-no">6283</span><span id="line-6283"> region.put(put);</span>
<span class="source-line-no">6284</span><span id="line-6284"> put = new Put(row2);</span>
<span class="source-line-no">6285</span><span id="line-6285"> put.add(kv2_4_2);</span>
<span class="source-line-no">6286</span><span id="line-6286"> put.add(kv2_4_3);</span>
<span class="source-line-no">6287</span><span id="line-6287"> region.put(put);</span>
<span class="source-line-no">6288</span><span id="line-6288"> put = new Put(row3);</span>
<span class="source-line-no">6289</span><span id="line-6289"> put.add(kv3_2_2);</span>
<span class="source-line-no">6290</span><span id="line-6290"> region.put(put);</span>
<span class="source-line-no">6291</span><span id="line-6291"> region.flush(true);</span>
<span class="source-line-no">6292</span><span id="line-6292"> // memstore(cf1/cf2/cf3) : "row0" (1 kvs) / "row3" ( 1 kv) / "row5" (max)</span>
<span class="source-line-no">6293</span><span id="line-6293"> // ( 2 kv)</span>
<span class="source-line-no">6294</span><span id="line-6294"> put = new Put(row0);</span>
<span class="source-line-no">6295</span><span id="line-6295"> put.add(kv0_1_1);</span>
<span class="source-line-no">6296</span><span id="line-6296"> region.put(put);</span>
<span class="source-line-no">6297</span><span id="line-6297"> put = new Put(row3);</span>
<span class="source-line-no">6298</span><span id="line-6298"> put.add(kv3_2_1);</span>
<span class="source-line-no">6299</span><span id="line-6299"> region.put(put);</span>
<span class="source-line-no">6300</span><span id="line-6300"> put = new Put(row5);</span>
<span class="source-line-no">6301</span><span id="line-6301"> put.add(kv5_2_1);</span>
<span class="source-line-no">6302</span><span id="line-6302"> put.add(kv5_2_2);</span>
<span class="source-line-no">6303</span><span id="line-6303"> region.put(put);</span>
<span class="source-line-no">6304</span><span id="line-6304"> // scan range = ["row4", min), skip the max "row5"</span>
<span class="source-line-no">6305</span><span id="line-6305"> Scan scan = new Scan().withStartRow(row4);</span>
<span class="source-line-no">6306</span><span id="line-6306"> scan.readVersions(5);</span>
<span class="source-line-no">6307</span><span id="line-6307"> scan.setBatch(3);</span>
<span class="source-line-no">6308</span><span id="line-6308"> scan.setReversed(true);</span>
<span class="source-line-no">6309</span><span id="line-6309"> try (InternalScanner scanner = region.getScanner(scan)) {</span>
<span class="source-line-no">6310</span><span id="line-6310"> List&lt;Cell&gt; currRow = new ArrayList&lt;&gt;();</span>
<span class="source-line-no">6311</span><span id="line-6311"> boolean hasNext = false;</span>
<span class="source-line-no">6312</span><span id="line-6312"> // 1. scan out "row4" (5 kvs), "row5" can't be scanned out since not</span>
<span class="source-line-no">6313</span><span id="line-6313"> // included in scan range</span>
<span class="source-line-no">6314</span><span id="line-6314"> // "row4" takes 2 next() calls since batch=3</span>
<span class="source-line-no">6315</span><span id="line-6315"> hasNext = scanner.next(currRow);</span>
<span class="source-line-no">6316</span><span id="line-6316"> assertEquals(3, currRow.size());</span>
<span class="source-line-no">6317</span><span id="line-6317"> assertTrue(Bytes.equals(currRow.get(0).getRowArray(), currRow.get(0).getRowOffset(),</span>
<span class="source-line-no">6318</span><span id="line-6318"> currRow.get(0).getRowLength(), row4, 0, row4.length));</span>
<span class="source-line-no">6319</span><span id="line-6319"> assertTrue(hasNext);</span>
<span class="source-line-no">6320</span><span id="line-6320"> currRow.clear();</span>
<span class="source-line-no">6321</span><span id="line-6321"> hasNext = scanner.next(currRow);</span>
<span class="source-line-no">6322</span><span id="line-6322"> assertEquals(2, currRow.size());</span>
<span class="source-line-no">6323</span><span id="line-6323"> assertTrue(Bytes.equals(currRow.get(0).getRowArray(), currRow.get(0).getRowOffset(),</span>
<span class="source-line-no">6324</span><span id="line-6324"> currRow.get(0).getRowLength(), row4, 0, row4.length));</span>
<span class="source-line-no">6325</span><span id="line-6325"> assertTrue(hasNext);</span>
<span class="source-line-no">6326</span><span id="line-6326"> // 2. scan out "row3" (2 kv)</span>
<span class="source-line-no">6327</span><span id="line-6327"> currRow.clear();</span>
<span class="source-line-no">6328</span><span id="line-6328"> hasNext = scanner.next(currRow);</span>
<span class="source-line-no">6329</span><span id="line-6329"> assertEquals(2, currRow.size());</span>
<span class="source-line-no">6330</span><span id="line-6330"> assertTrue(Bytes.equals(currRow.get(0).getRowArray(), currRow.get(0).getRowOffset(),</span>
<span class="source-line-no">6331</span><span id="line-6331"> currRow.get(0).getRowLength(), row3, 0, row3.length));</span>
<span class="source-line-no">6332</span><span id="line-6332"> assertTrue(hasNext);</span>
<span class="source-line-no">6333</span><span id="line-6333"> // 3. scan out "row2" (4 kvs)</span>
<span class="source-line-no">6334</span><span id="line-6334"> // "row2" takes 2 next() calls since batch=3</span>
<span class="source-line-no">6335</span><span id="line-6335"> currRow.clear();</span>
<span class="source-line-no">6336</span><span id="line-6336"> hasNext = scanner.next(currRow);</span>
<span class="source-line-no">6337</span><span id="line-6337"> assertEquals(3, currRow.size());</span>
<span class="source-line-no">6338</span><span id="line-6338"> assertTrue(Bytes.equals(currRow.get(0).getRowArray(), currRow.get(0).getRowOffset(),</span>
<span class="source-line-no">6339</span><span id="line-6339"> currRow.get(0).getRowLength(), row2, 0, row2.length));</span>
<span class="source-line-no">6340</span><span id="line-6340"> assertTrue(hasNext);</span>
<span class="source-line-no">6341</span><span id="line-6341"> currRow.clear();</span>
<span class="source-line-no">6342</span><span id="line-6342"> hasNext = scanner.next(currRow);</span>
<span class="source-line-no">6343</span><span id="line-6343"> assertEquals(1, currRow.size());</span>
<span class="source-line-no">6344</span><span id="line-6344"> assertTrue(Bytes.equals(currRow.get(0).getRowArray(), currRow.get(0).getRowOffset(),</span>
<span class="source-line-no">6345</span><span id="line-6345"> currRow.get(0).getRowLength(), row2, 0, row2.length));</span>
<span class="source-line-no">6346</span><span id="line-6346"> assertTrue(hasNext);</span>
<span class="source-line-no">6347</span><span id="line-6347"> // 4. scan out "row1" (2 kv)</span>
<span class="source-line-no">6348</span><span id="line-6348"> currRow.clear();</span>
<span class="source-line-no">6349</span><span id="line-6349"> hasNext = scanner.next(currRow);</span>
<span class="source-line-no">6350</span><span id="line-6350"> assertEquals(2, currRow.size());</span>
<span class="source-line-no">6351</span><span id="line-6351"> assertTrue(Bytes.equals(currRow.get(0).getRowArray(), currRow.get(0).getRowOffset(),</span>
<span class="source-line-no">6352</span><span id="line-6352"> currRow.get(0).getRowLength(), row1, 0, row1.length));</span>
<span class="source-line-no">6353</span><span id="line-6353"> assertTrue(hasNext);</span>
<span class="source-line-no">6354</span><span id="line-6354"> // 5. scan out "row0" (1 kv)</span>
<span class="source-line-no">6355</span><span id="line-6355"> currRow.clear();</span>
<span class="source-line-no">6356</span><span id="line-6356"> hasNext = scanner.next(currRow);</span>
<span class="source-line-no">6357</span><span id="line-6357"> assertEquals(1, currRow.size());</span>
<span class="source-line-no">6358</span><span id="line-6358"> assertTrue(Bytes.equals(currRow.get(0).getRowArray(), currRow.get(0).getRowOffset(),</span>
<span class="source-line-no">6359</span><span id="line-6359"> currRow.get(0).getRowLength(), row0, 0, row0.length));</span>
<span class="source-line-no">6360</span><span id="line-6360"> assertFalse(hasNext);</span>
<span class="source-line-no">6361</span><span id="line-6361"> }</span>
<span class="source-line-no">6362</span><span id="line-6362"> }</span>
<span class="source-line-no">6363</span><span id="line-6363"></span>
<span class="source-line-no">6364</span><span id="line-6364"> @Test</span>
<span class="source-line-no">6365</span><span id="line-6365"> public void testReverseScanner_FromMemStoreAndHFiles_MultiCFs2() throws IOException {</span>
<span class="source-line-no">6366</span><span id="line-6366"> byte[] row1 = Bytes.toBytes("row1");</span>
<span class="source-line-no">6367</span><span id="line-6367"> byte[] row2 = Bytes.toBytes("row2");</span>
<span class="source-line-no">6368</span><span id="line-6368"> byte[] row3 = Bytes.toBytes("row3");</span>
<span class="source-line-no">6369</span><span id="line-6369"> byte[] row4 = Bytes.toBytes("row4");</span>
<span class="source-line-no">6370</span><span id="line-6370"> byte[] cf1 = Bytes.toBytes("CF1");</span>
<span class="source-line-no">6371</span><span id="line-6371"> byte[] cf2 = Bytes.toBytes("CF2");</span>
<span class="source-line-no">6372</span><span id="line-6372"> byte[] cf3 = Bytes.toBytes("CF3");</span>
<span class="source-line-no">6373</span><span id="line-6373"> byte[] cf4 = Bytes.toBytes("CF4");</span>
<span class="source-line-no">6374</span><span id="line-6374"> byte[][] families = { cf1, cf2, cf3, cf4 };</span>
<span class="source-line-no">6375</span><span id="line-6375"> byte[] col = Bytes.toBytes("C");</span>
<span class="source-line-no">6376</span><span id="line-6376"> long ts = 1;</span>
<span class="source-line-no">6377</span><span id="line-6377"> Configuration conf = new Configuration(CONF);</span>
<span class="source-line-no">6378</span><span id="line-6378"> // disable compactions in this test.</span>
<span class="source-line-no">6379</span><span id="line-6379"> conf.setInt("hbase.hstore.compactionThreshold", 10000);</span>
<span class="source-line-no">6380</span><span id="line-6380"> this.region = initHRegion(tableName, method, conf, families);</span>
<span class="source-line-no">6381</span><span id="line-6381"> KeyValue kv1 = new KeyValue(row1, cf1, col, ts, KeyValue.Type.Put, null);</span>
<span class="source-line-no">6382</span><span id="line-6382"> KeyValue kv2 = new KeyValue(row2, cf2, col, ts, KeyValue.Type.Put, null);</span>
<span class="source-line-no">6383</span><span id="line-6383"> KeyValue kv3 = new KeyValue(row3, cf3, col, ts, KeyValue.Type.Put, null);</span>
<span class="source-line-no">6384</span><span id="line-6384"> KeyValue kv4 = new KeyValue(row4, cf4, col, ts, KeyValue.Type.Put, null);</span>
<span class="source-line-no">6385</span><span id="line-6385"> // storefile1</span>
<span class="source-line-no">6386</span><span id="line-6386"> Put put = new Put(row1);</span>
<span class="source-line-no">6387</span><span id="line-6387"> put.add(kv1);</span>
<span class="source-line-no">6388</span><span id="line-6388"> region.put(put);</span>
<span class="source-line-no">6389</span><span id="line-6389"> region.flush(true);</span>
<span class="source-line-no">6390</span><span id="line-6390"> // storefile2</span>
<span class="source-line-no">6391</span><span id="line-6391"> put = new Put(row2);</span>
<span class="source-line-no">6392</span><span id="line-6392"> put.add(kv2);</span>
<span class="source-line-no">6393</span><span id="line-6393"> region.put(put);</span>
<span class="source-line-no">6394</span><span id="line-6394"> region.flush(true);</span>
<span class="source-line-no">6395</span><span id="line-6395"> // storefile3</span>
<span class="source-line-no">6396</span><span id="line-6396"> put = new Put(row3);</span>
<span class="source-line-no">6397</span><span id="line-6397"> put.add(kv3);</span>
<span class="source-line-no">6398</span><span id="line-6398"> region.put(put);</span>
<span class="source-line-no">6399</span><span id="line-6399"> region.flush(true);</span>
<span class="source-line-no">6400</span><span id="line-6400"> // memstore</span>
<span class="source-line-no">6401</span><span id="line-6401"> put = new Put(row4);</span>
<span class="source-line-no">6402</span><span id="line-6402"> put.add(kv4);</span>
<span class="source-line-no">6403</span><span id="line-6403"> region.put(put);</span>
<span class="source-line-no">6404</span><span id="line-6404"> // scan range = ["row4", min)</span>
<span class="source-line-no">6405</span><span id="line-6405"> Scan scan = new Scan().withStartRow(row4);</span>
<span class="source-line-no">6406</span><span id="line-6406"> scan.setReversed(true);</span>
<span class="source-line-no">6407</span><span id="line-6407"> scan.setBatch(10);</span>
<span class="source-line-no">6408</span><span id="line-6408"> try (InternalScanner scanner = region.getScanner(scan)) {</span>
<span class="source-line-no">6409</span><span id="line-6409"> List&lt;Cell&gt; currRow = new ArrayList&lt;&gt;();</span>
<span class="source-line-no">6410</span><span id="line-6410"> boolean hasNext = scanner.next(currRow);</span>
<span class="source-line-no">6411</span><span id="line-6411"> assertEquals(1, currRow.size());</span>
<span class="source-line-no">6412</span><span id="line-6412"> assertTrue(Bytes.equals(currRow.get(0).getRowArray(), currRow.get(0).getRowOffset(),</span>
<span class="source-line-no">6413</span><span id="line-6413"> currRow.get(0).getRowLength(), row4, 0, row4.length));</span>
<span class="source-line-no">6414</span><span id="line-6414"> assertTrue(hasNext);</span>
<span class="source-line-no">6415</span><span id="line-6415"> currRow.clear();</span>
<span class="source-line-no">6416</span><span id="line-6416"> hasNext = scanner.next(currRow);</span>
<span class="source-line-no">6417</span><span id="line-6417"> assertEquals(1, currRow.size());</span>
<span class="source-line-no">6418</span><span id="line-6418"> assertTrue(Bytes.equals(currRow.get(0).getRowArray(), currRow.get(0).getRowOffset(),</span>
<span class="source-line-no">6419</span><span id="line-6419"> currRow.get(0).getRowLength(), row3, 0, row3.length));</span>
<span class="source-line-no">6420</span><span id="line-6420"> assertTrue(hasNext);</span>
<span class="source-line-no">6421</span><span id="line-6421"> currRow.clear();</span>
<span class="source-line-no">6422</span><span id="line-6422"> hasNext = scanner.next(currRow);</span>
<span class="source-line-no">6423</span><span id="line-6423"> assertEquals(1, currRow.size());</span>
<span class="source-line-no">6424</span><span id="line-6424"> assertTrue(Bytes.equals(currRow.get(0).getRowArray(), currRow.get(0).getRowOffset(),</span>
<span class="source-line-no">6425</span><span id="line-6425"> currRow.get(0).getRowLength(), row2, 0, row2.length));</span>
<span class="source-line-no">6426</span><span id="line-6426"> assertTrue(hasNext);</span>
<span class="source-line-no">6427</span><span id="line-6427"> currRow.clear();</span>
<span class="source-line-no">6428</span><span id="line-6428"> hasNext = scanner.next(currRow);</span>
<span class="source-line-no">6429</span><span id="line-6429"> assertEquals(1, currRow.size());</span>
<span class="source-line-no">6430</span><span id="line-6430"> assertTrue(Bytes.equals(currRow.get(0).getRowArray(), currRow.get(0).getRowOffset(),</span>
<span class="source-line-no">6431</span><span id="line-6431"> currRow.get(0).getRowLength(), row1, 0, row1.length));</span>
<span class="source-line-no">6432</span><span id="line-6432"> assertFalse(hasNext);</span>
<span class="source-line-no">6433</span><span id="line-6433"> }</span>
<span class="source-line-no">6434</span><span id="line-6434"> }</span>
<span class="source-line-no">6435</span><span id="line-6435"></span>
<span class="source-line-no">6436</span><span id="line-6436"> /**</span>
<span class="source-line-no">6437</span><span id="line-6437"> * Test for HBASE-14497: Reverse Scan threw StackOverflow caused by readPt checking</span>
<span class="source-line-no">6438</span><span id="line-6438"> */</span>
<span class="source-line-no">6439</span><span id="line-6439"> @Test</span>
<span class="source-line-no">6440</span><span id="line-6440"> public void testReverseScanner_StackOverflow() throws IOException {</span>
<span class="source-line-no">6441</span><span id="line-6441"> byte[] cf1 = Bytes.toBytes("CF1");</span>
<span class="source-line-no">6442</span><span id="line-6442"> byte[][] families = { cf1 };</span>
<span class="source-line-no">6443</span><span id="line-6443"> byte[] col = Bytes.toBytes("C");</span>
<span class="source-line-no">6444</span><span id="line-6444"> Configuration conf = new Configuration(CONF);</span>
<span class="source-line-no">6445</span><span id="line-6445"> this.region = initHRegion(tableName, method, conf, families);</span>
<span class="source-line-no">6446</span><span id="line-6446"> // setup with one storefile and one memstore, to create scanner and get an earlier readPt</span>
<span class="source-line-no">6447</span><span id="line-6447"> Put put = new Put(Bytes.toBytes("19998"));</span>
<span class="source-line-no">6448</span><span id="line-6448"> put.addColumn(cf1, col, Bytes.toBytes("val"));</span>
<span class="source-line-no">6449</span><span id="line-6449"> region.put(put);</span>
<span class="source-line-no">6450</span><span id="line-6450"> region.flushcache(true, true, FlushLifeCycleTracker.DUMMY);</span>
<span class="source-line-no">6451</span><span id="line-6451"> Put put2 = new Put(Bytes.toBytes("19997"));</span>
<span class="source-line-no">6452</span><span id="line-6452"> put2.addColumn(cf1, col, Bytes.toBytes("val"));</span>
<span class="source-line-no">6453</span><span id="line-6453"> region.put(put2);</span>
<span class="source-line-no">6454</span><span id="line-6454"></span>
<span class="source-line-no">6455</span><span id="line-6455"> Scan scan = new Scan().withStartRow(Bytes.toBytes("19998"));</span>
<span class="source-line-no">6456</span><span id="line-6456"> scan.setReversed(true);</span>
<span class="source-line-no">6457</span><span id="line-6457"> try (InternalScanner scanner = region.getScanner(scan)) {</span>
<span class="source-line-no">6458</span><span id="line-6458"> // create one storefile contains many rows will be skipped</span>
<span class="source-line-no">6459</span><span id="line-6459"> // to check StoreFileScanner.seekToPreviousRow</span>
<span class="source-line-no">6460</span><span id="line-6460"> for (int i = 10000; i &lt; 20000; i++) {</span>
<span class="source-line-no">6461</span><span id="line-6461"> Put p = new Put(Bytes.toBytes("" + i));</span>
<span class="source-line-no">6462</span><span id="line-6462"> p.addColumn(cf1, col, Bytes.toBytes("" + i));</span>
<span class="source-line-no">6463</span><span id="line-6463"> region.put(p);</span>
<span class="source-line-no">6464</span><span id="line-6464"> }</span>
<span class="source-line-no">6465</span><span id="line-6465"> region.flushcache(true, true, FlushLifeCycleTracker.DUMMY);</span>
<span class="source-line-no">6466</span><span id="line-6466"></span>
<span class="source-line-no">6467</span><span id="line-6467"> // create one memstore contains many rows will be skipped</span>
<span class="source-line-no">6468</span><span id="line-6468"> // to check MemStoreScanner.seekToPreviousRow</span>
<span class="source-line-no">6469</span><span id="line-6469"> for (int i = 10000; i &lt; 20000; i++) {</span>
<span class="source-line-no">6470</span><span id="line-6470"> Put p = new Put(Bytes.toBytes("" + i));</span>
<span class="source-line-no">6471</span><span id="line-6471"> p.addColumn(cf1, col, Bytes.toBytes("" + i));</span>
<span class="source-line-no">6472</span><span id="line-6472"> region.put(p);</span>
<span class="source-line-no">6473</span><span id="line-6473"> }</span>
<span class="source-line-no">6474</span><span id="line-6474"></span>
<span class="source-line-no">6475</span><span id="line-6475"> List&lt;Cell&gt; currRow = new ArrayList&lt;&gt;();</span>
<span class="source-line-no">6476</span><span id="line-6476"> boolean hasNext;</span>
<span class="source-line-no">6477</span><span id="line-6477"> do {</span>
<span class="source-line-no">6478</span><span id="line-6478"> hasNext = scanner.next(currRow);</span>
<span class="source-line-no">6479</span><span id="line-6479"> } while (hasNext);</span>
<span class="source-line-no">6480</span><span id="line-6480"> assertEquals(2, currRow.size());</span>
<span class="source-line-no">6481</span><span id="line-6481"> assertEquals("19998", Bytes.toString(currRow.get(0).getRowArray(),</span>
<span class="source-line-no">6482</span><span id="line-6482"> currRow.get(0).getRowOffset(), currRow.get(0).getRowLength()));</span>
<span class="source-line-no">6483</span><span id="line-6483"> assertEquals("19997", Bytes.toString(currRow.get(1).getRowArray(),</span>
<span class="source-line-no">6484</span><span id="line-6484"> currRow.get(1).getRowOffset(), currRow.get(1).getRowLength()));</span>
<span class="source-line-no">6485</span><span id="line-6485"> }</span>
<span class="source-line-no">6486</span><span id="line-6486"> }</span>
<span class="source-line-no">6487</span><span id="line-6487"></span>
<span class="source-line-no">6488</span><span id="line-6488"> @Test</span>
<span class="source-line-no">6489</span><span id="line-6489"> public void testReverseScanShouldNotScanMemstoreIfReadPtLesser() throws Exception {</span>
<span class="source-line-no">6490</span><span id="line-6490"> byte[] cf1 = Bytes.toBytes("CF1");</span>
<span class="source-line-no">6491</span><span id="line-6491"> byte[][] families = { cf1 };</span>
<span class="source-line-no">6492</span><span id="line-6492"> byte[] col = Bytes.toBytes("C");</span>
<span class="source-line-no">6493</span><span id="line-6493"> this.region = initHRegion(tableName, method, CONF, families);</span>
<span class="source-line-no">6494</span><span id="line-6494"> // setup with one storefile and one memstore, to create scanner and get an earlier readPt</span>
<span class="source-line-no">6495</span><span id="line-6495"> Put put = new Put(Bytes.toBytes("19996"));</span>
<span class="source-line-no">6496</span><span id="line-6496"> put.addColumn(cf1, col, Bytes.toBytes("val"));</span>
<span class="source-line-no">6497</span><span id="line-6497"> region.put(put);</span>
<span class="source-line-no">6498</span><span id="line-6498"> Put put2 = new Put(Bytes.toBytes("19995"));</span>
<span class="source-line-no">6499</span><span id="line-6499"> put2.addColumn(cf1, col, Bytes.toBytes("val"));</span>
<span class="source-line-no">6500</span><span id="line-6500"> region.put(put2);</span>
<span class="source-line-no">6501</span><span id="line-6501"> // create a reverse scan</span>
<span class="source-line-no">6502</span><span id="line-6502"> Scan scan = new Scan().withStartRow(Bytes.toBytes("19996"));</span>
<span class="source-line-no">6503</span><span id="line-6503"> scan.setReversed(true);</span>
<span class="source-line-no">6504</span><span id="line-6504"> try (RegionScannerImpl scanner = region.getScanner(scan)) {</span>
<span class="source-line-no">6505</span><span id="line-6505"> // flush the cache. This will reset the store scanner</span>
<span class="source-line-no">6506</span><span id="line-6506"> region.flushcache(true, true, FlushLifeCycleTracker.DUMMY);</span>
<span class="source-line-no">6507</span><span id="line-6507"></span>
<span class="source-line-no">6508</span><span id="line-6508"> // create one memstore contains many rows will be skipped</span>
<span class="source-line-no">6509</span><span id="line-6509"> // to check MemStoreScanner.seekToPreviousRow</span>
<span class="source-line-no">6510</span><span id="line-6510"> for (int i = 10000; i &lt; 20000; i++) {</span>
<span class="source-line-no">6511</span><span id="line-6511"> Put p = new Put(Bytes.toBytes("" + i));</span>
<span class="source-line-no">6512</span><span id="line-6512"> p.addColumn(cf1, col, Bytes.toBytes("" + i));</span>
<span class="source-line-no">6513</span><span id="line-6513"> region.put(p);</span>
<span class="source-line-no">6514</span><span id="line-6514"> }</span>
<span class="source-line-no">6515</span><span id="line-6515"> List&lt;Cell&gt; currRow = new ArrayList&lt;&gt;();</span>
<span class="source-line-no">6516</span><span id="line-6516"> boolean hasNext;</span>
<span class="source-line-no">6517</span><span id="line-6517"> boolean assertDone = false;</span>
<span class="source-line-no">6518</span><span id="line-6518"> do {</span>
<span class="source-line-no">6519</span><span id="line-6519"> hasNext = scanner.next(currRow);</span>
<span class="source-line-no">6520</span><span id="line-6520"> // With HBASE-15871, after the scanner is reset the memstore scanner should not be</span>
<span class="source-line-no">6521</span><span id="line-6521"> // added here</span>
<span class="source-line-no">6522</span><span id="line-6522"> if (!assertDone) {</span>
<span class="source-line-no">6523</span><span id="line-6523"> StoreScanner current = (StoreScanner) (scanner.storeHeap).getCurrentForTesting();</span>
<span class="source-line-no">6524</span><span id="line-6524"> List&lt;KeyValueScanner&gt; scanners = current.getAllScannersForTesting();</span>
<span class="source-line-no">6525</span><span id="line-6525"> assertEquals("There should be only one scanner the store file scanner", 1,</span>
<span class="source-line-no">6526</span><span id="line-6526"> scanners.size());</span>
<span class="source-line-no">6527</span><span id="line-6527"> assertDone = true;</span>
<span class="source-line-no">6528</span><span id="line-6528"> }</span>
<span class="source-line-no">6529</span><span id="line-6529"> } while (hasNext);</span>
<span class="source-line-no">6530</span><span id="line-6530"> assertEquals(2, currRow.size());</span>
<span class="source-line-no">6531</span><span id="line-6531"> assertEquals("19996", Bytes.toString(currRow.get(0).getRowArray(),</span>
<span class="source-line-no">6532</span><span id="line-6532"> currRow.get(0).getRowOffset(), currRow.get(0).getRowLength()));</span>
<span class="source-line-no">6533</span><span id="line-6533"> assertEquals("19995", Bytes.toString(currRow.get(1).getRowArray(),</span>
<span class="source-line-no">6534</span><span id="line-6534"> currRow.get(1).getRowOffset(), currRow.get(1).getRowLength()));</span>
<span class="source-line-no">6535</span><span id="line-6535"> }</span>
<span class="source-line-no">6536</span><span id="line-6536"> }</span>
<span class="source-line-no">6537</span><span id="line-6537"></span>
<span class="source-line-no">6538</span><span id="line-6538"> @Test</span>
<span class="source-line-no">6539</span><span id="line-6539"> public void testReverseScanWhenPutCellsAfterOpenReverseScan() throws Exception {</span>
<span class="source-line-no">6540</span><span id="line-6540"> byte[] cf1 = Bytes.toBytes("CF1");</span>
<span class="source-line-no">6541</span><span id="line-6541"> byte[][] families = { cf1 };</span>
<span class="source-line-no">6542</span><span id="line-6542"> byte[] col = Bytes.toBytes("C");</span>
<span class="source-line-no">6543</span><span id="line-6543"></span>
<span class="source-line-no">6544</span><span id="line-6544"> this.region = initHRegion(tableName, method, CONF, families);</span>
<span class="source-line-no">6545</span><span id="line-6545"></span>
<span class="source-line-no">6546</span><span id="line-6546"> Put put = new Put(Bytes.toBytes("199996"));</span>
<span class="source-line-no">6547</span><span id="line-6547"> put.addColumn(cf1, col, Bytes.toBytes("val"));</span>
<span class="source-line-no">6548</span><span id="line-6548"> region.put(put);</span>
<span class="source-line-no">6549</span><span id="line-6549"> Put put2 = new Put(Bytes.toBytes("199995"));</span>
<span class="source-line-no">6550</span><span id="line-6550"> put2.addColumn(cf1, col, Bytes.toBytes("val"));</span>
<span class="source-line-no">6551</span><span id="line-6551"> region.put(put2);</span>
<span class="source-line-no">6552</span><span id="line-6552"></span>
<span class="source-line-no">6553</span><span id="line-6553"> // Create a reverse scan</span>
<span class="source-line-no">6554</span><span id="line-6554"> Scan scan = new Scan().withStartRow(Bytes.toBytes("199996"));</span>
<span class="source-line-no">6555</span><span id="line-6555"> scan.setReversed(true);</span>
<span class="source-line-no">6556</span><span id="line-6556"> try (RegionScannerImpl scanner = region.getScanner(scan)) {</span>
<span class="source-line-no">6557</span><span id="line-6557"> // Put a lot of cells that have sequenceIDs grater than the readPt of the reverse scan</span>
<span class="source-line-no">6558</span><span id="line-6558"> for (int i = 100000; i &lt; 200000; i++) {</span>
<span class="source-line-no">6559</span><span id="line-6559"> Put p = new Put(Bytes.toBytes("" + i));</span>
<span class="source-line-no">6560</span><span id="line-6560"> p.addColumn(cf1, col, Bytes.toBytes("" + i));</span>
<span class="source-line-no">6561</span><span id="line-6561"> region.put(p);</span>
<span class="source-line-no">6562</span><span id="line-6562"> }</span>
<span class="source-line-no">6563</span><span id="line-6563"> List&lt;Cell&gt; currRow = new ArrayList&lt;&gt;();</span>
<span class="source-line-no">6564</span><span id="line-6564"> boolean hasNext;</span>
<span class="source-line-no">6565</span><span id="line-6565"> do {</span>
<span class="source-line-no">6566</span><span id="line-6566"> hasNext = scanner.next(currRow);</span>
<span class="source-line-no">6567</span><span id="line-6567"> } while (hasNext);</span>
<span class="source-line-no">6568</span><span id="line-6568"></span>
<span class="source-line-no">6569</span><span id="line-6569"> assertEquals(2, currRow.size());</span>
<span class="source-line-no">6570</span><span id="line-6570"> assertEquals("199996", Bytes.toString(currRow.get(0).getRowArray(),</span>
<span class="source-line-no">6571</span><span id="line-6571"> currRow.get(0).getRowOffset(), currRow.get(0).getRowLength()));</span>
<span class="source-line-no">6572</span><span id="line-6572"> assertEquals("199995", Bytes.toString(currRow.get(1).getRowArray(),</span>
<span class="source-line-no">6573</span><span id="line-6573"> currRow.get(1).getRowOffset(), currRow.get(1).getRowLength()));</span>
<span class="source-line-no">6574</span><span id="line-6574"> }</span>
<span class="source-line-no">6575</span><span id="line-6575"> }</span>
<span class="source-line-no">6576</span><span id="line-6576"></span>
<span class="source-line-no">6577</span><span id="line-6577"> @Test</span>
<span class="source-line-no">6578</span><span id="line-6578"> public void testWriteRequestsCounter() throws IOException {</span>
<span class="source-line-no">6579</span><span id="line-6579"> byte[] fam = Bytes.toBytes("info");</span>
<span class="source-line-no">6580</span><span id="line-6580"> byte[][] families = { fam };</span>
<span class="source-line-no">6581</span><span id="line-6581"> this.region = initHRegion(tableName, method, CONF, families);</span>
<span class="source-line-no">6582</span><span id="line-6582"></span>
<span class="source-line-no">6583</span><span id="line-6583"> Assert.assertEquals(0L, region.getWriteRequestsCount());</span>
<span class="source-line-no">6584</span><span id="line-6584"></span>
<span class="source-line-no">6585</span><span id="line-6585"> Put put = new Put(row);</span>
<span class="source-line-no">6586</span><span id="line-6586"> put.addColumn(fam, fam, fam);</span>
<span class="source-line-no">6587</span><span id="line-6587"></span>
<span class="source-line-no">6588</span><span id="line-6588"> Assert.assertEquals(0L, region.getWriteRequestsCount());</span>
<span class="source-line-no">6589</span><span id="line-6589"> region.put(put);</span>
<span class="source-line-no">6590</span><span id="line-6590"> Assert.assertEquals(1L, region.getWriteRequestsCount());</span>
<span class="source-line-no">6591</span><span id="line-6591"> region.put(put);</span>
<span class="source-line-no">6592</span><span id="line-6592"> Assert.assertEquals(2L, region.getWriteRequestsCount());</span>
<span class="source-line-no">6593</span><span id="line-6593"> region.put(put);</span>
<span class="source-line-no">6594</span><span id="line-6594"> Assert.assertEquals(3L, region.getWriteRequestsCount());</span>
<span class="source-line-no">6595</span><span id="line-6595"></span>
<span class="source-line-no">6596</span><span id="line-6596"> region.delete(new Delete(row));</span>
<span class="source-line-no">6597</span><span id="line-6597"> Assert.assertEquals(4L, region.getWriteRequestsCount());</span>
<span class="source-line-no">6598</span><span id="line-6598"> }</span>
<span class="source-line-no">6599</span><span id="line-6599"></span>
<span class="source-line-no">6600</span><span id="line-6600"> @Test</span>
<span class="source-line-no">6601</span><span id="line-6601"> public void testOpenRegionWrittenToWAL() throws Exception {</span>
<span class="source-line-no">6602</span><span id="line-6602"> final ServerName serverName = ServerName.valueOf(name.getMethodName(), 100, 42);</span>
<span class="source-line-no">6603</span><span id="line-6603"> final RegionServerServices rss = spy(TEST_UTIL.createMockRegionServerService(serverName));</span>
<span class="source-line-no">6604</span><span id="line-6604"></span>
<span class="source-line-no">6605</span><span id="line-6605"> TableDescriptor htd = TableDescriptorBuilder.newBuilder(TableName.valueOf(name.getMethodName()))</span>
<span class="source-line-no">6606</span><span id="line-6606"> .setColumnFamily(ColumnFamilyDescriptorBuilder.of(fam1))</span>
<span class="source-line-no">6607</span><span id="line-6607"> .setColumnFamily(ColumnFamilyDescriptorBuilder.of(fam2)).build();</span>
<span class="source-line-no">6608</span><span id="line-6608"> RegionInfo hri = RegionInfoBuilder.newBuilder(htd.getTableName()).build();</span>
<span class="source-line-no">6609</span><span id="line-6609"></span>
<span class="source-line-no">6610</span><span id="line-6610"> // open the region w/o rss and wal and flush some files</span>
<span class="source-line-no">6611</span><span id="line-6611"> region = HBaseTestingUtil.createRegionAndWAL(hri, TEST_UTIL.getDataTestDir(),</span>
<span class="source-line-no">6612</span><span id="line-6612"> TEST_UTIL.getConfiguration(), htd);</span>
<span class="source-line-no">6613</span><span id="line-6613"> assertNotNull(region);</span>
<span class="source-line-no">6614</span><span id="line-6614"></span>
<span class="source-line-no">6615</span><span id="line-6615"> // create a file in fam1 for the region before opening in OpenRegionHandler</span>
<span class="source-line-no">6616</span><span id="line-6616"> region.put(new Put(Bytes.toBytes("a")).addColumn(fam1, fam1, fam1));</span>
<span class="source-line-no">6617</span><span id="line-6617"> region.flush(true);</span>
<span class="source-line-no">6618</span><span id="line-6618"> HBaseTestingUtil.closeRegionAndWAL(region);</span>
<span class="source-line-no">6619</span><span id="line-6619"></span>
<span class="source-line-no">6620</span><span id="line-6620"> ArgumentCaptor&lt;WALEdit&gt; editCaptor = ArgumentCaptor.forClass(WALEdit.class);</span>
<span class="source-line-no">6621</span><span id="line-6621"></span>
<span class="source-line-no">6622</span><span id="line-6622"> // capture append() calls</span>
<span class="source-line-no">6623</span><span id="line-6623"> WAL wal = mockWAL();</span>
<span class="source-line-no">6624</span><span id="line-6624"> when(rss.getWAL(any(RegionInfo.class))).thenReturn(wal);</span>
<span class="source-line-no">6625</span><span id="line-6625"></span>
<span class="source-line-no">6626</span><span id="line-6626"> region =</span>
<span class="source-line-no">6627</span><span id="line-6627"> HRegion.openHRegion(hri, htd, rss.getWAL(hri), TEST_UTIL.getConfiguration(), rss, null);</span>
<span class="source-line-no">6628</span><span id="line-6628"></span>
<span class="source-line-no">6629</span><span id="line-6629"> verify(wal, times(1)).appendMarker(any(RegionInfo.class), any(WALKeyImpl.class),</span>
<span class="source-line-no">6630</span><span id="line-6630"> editCaptor.capture());</span>
<span class="source-line-no">6631</span><span id="line-6631"></span>
<span class="source-line-no">6632</span><span id="line-6632"> WALEdit edit = editCaptor.getValue();</span>
<span class="source-line-no">6633</span><span id="line-6633"> assertNotNull(edit);</span>
<span class="source-line-no">6634</span><span id="line-6634"> assertNotNull(edit.getCells());</span>
<span class="source-line-no">6635</span><span id="line-6635"> assertEquals(1, edit.getCells().size());</span>
<span class="source-line-no">6636</span><span id="line-6636"> RegionEventDescriptor desc = WALEdit.getRegionEventDescriptor(edit.getCells().get(0));</span>
<span class="source-line-no">6637</span><span id="line-6637"> assertNotNull(desc);</span>
<span class="source-line-no">6638</span><span id="line-6638"></span>
<span class="source-line-no">6639</span><span id="line-6639"> LOG.info("RegionEventDescriptor from WAL: " + desc);</span>
<span class="source-line-no">6640</span><span id="line-6640"></span>
<span class="source-line-no">6641</span><span id="line-6641"> assertEquals(RegionEventDescriptor.EventType.REGION_OPEN, desc.getEventType());</span>
<span class="source-line-no">6642</span><span id="line-6642"> assertTrue(Bytes.equals(desc.getTableName().toByteArray(), htd.getTableName().toBytes()));</span>
<span class="source-line-no">6643</span><span id="line-6643"> assertTrue(</span>
<span class="source-line-no">6644</span><span id="line-6644"> Bytes.equals(desc.getEncodedRegionName().toByteArray(), hri.getEncodedNameAsBytes()));</span>
<span class="source-line-no">6645</span><span id="line-6645"> assertTrue(desc.getLogSequenceNumber() &gt; 0);</span>
<span class="source-line-no">6646</span><span id="line-6646"> assertEquals(serverName, ProtobufUtil.toServerName(desc.getServer()));</span>
<span class="source-line-no">6647</span><span id="line-6647"> assertEquals(2, desc.getStoresCount());</span>
<span class="source-line-no">6648</span><span id="line-6648"></span>
<span class="source-line-no">6649</span><span id="line-6649"> StoreDescriptor store = desc.getStores(0);</span>
<span class="source-line-no">6650</span><span id="line-6650"> assertTrue(Bytes.equals(store.getFamilyName().toByteArray(), fam1));</span>
<span class="source-line-no">6651</span><span id="line-6651"> assertEquals(store.getStoreHomeDir(), Bytes.toString(fam1));</span>
<span class="source-line-no">6652</span><span id="line-6652"> assertEquals(1, store.getStoreFileCount()); // 1store file</span>
<span class="source-line-no">6653</span><span id="line-6653"> assertFalse(store.getStoreFile(0).contains("/")); // ensure path is relative</span>
<span class="source-line-no">6654</span><span id="line-6654"></span>
<span class="source-line-no">6655</span><span id="line-6655"> store = desc.getStores(1);</span>
<span class="source-line-no">6656</span><span id="line-6656"> assertTrue(Bytes.equals(store.getFamilyName().toByteArray(), fam2));</span>
<span class="source-line-no">6657</span><span id="line-6657"> assertEquals(store.getStoreHomeDir(), Bytes.toString(fam2));</span>
<span class="source-line-no">6658</span><span id="line-6658"> assertEquals(0, store.getStoreFileCount()); // no store files</span>
<span class="source-line-no">6659</span><span id="line-6659"> }</span>
<span class="source-line-no">6660</span><span id="line-6660"></span>
<span class="source-line-no">6661</span><span id="line-6661"> // Helper for test testOpenRegionWrittenToWALForLogReplay</span>
<span class="source-line-no">6662</span><span id="line-6662"> static class HRegionWithSeqId extends HRegion {</span>
<span class="source-line-no">6663</span><span id="line-6663"> public HRegionWithSeqId(final Path tableDir, final WAL wal, final FileSystem fs,</span>
<span class="source-line-no">6664</span><span id="line-6664"> final Configuration confParam, final RegionInfo regionInfo, final TableDescriptor htd,</span>
<span class="source-line-no">6665</span><span id="line-6665"> final RegionServerServices rsServices) {</span>
<span class="source-line-no">6666</span><span id="line-6666"> super(tableDir, wal, fs, confParam, regionInfo, htd, rsServices);</span>
<span class="source-line-no">6667</span><span id="line-6667"> }</span>
<span class="source-line-no">6668</span><span id="line-6668"></span>
<span class="source-line-no">6669</span><span id="line-6669"> @Override</span>
<span class="source-line-no">6670</span><span id="line-6670"> protected long getNextSequenceId(WAL wal) throws IOException {</span>
<span class="source-line-no">6671</span><span id="line-6671"> return 42;</span>
<span class="source-line-no">6672</span><span id="line-6672"> }</span>
<span class="source-line-no">6673</span><span id="line-6673"> }</span>
<span class="source-line-no">6674</span><span id="line-6674"></span>
<span class="source-line-no">6675</span><span id="line-6675"> @Test</span>
<span class="source-line-no">6676</span><span id="line-6676"> public void testFlushedFileWithNoTags() throws Exception {</span>
<span class="source-line-no">6677</span><span id="line-6677"> final TableName tableName = TableName.valueOf(name.getMethodName());</span>
<span class="source-line-no">6678</span><span id="line-6678"> TableDescriptor tableDescriptor = TableDescriptorBuilder.newBuilder(tableName)</span>
<span class="source-line-no">6679</span><span id="line-6679"> .setColumnFamily(ColumnFamilyDescriptorBuilder.of(fam1)).build();</span>
<span class="source-line-no">6680</span><span id="line-6680"> RegionInfo info = RegionInfoBuilder.newBuilder(tableName).build();</span>
<span class="source-line-no">6681</span><span id="line-6681"> Path path = TEST_UTIL.getDataTestDir(getClass().getSimpleName());</span>
<span class="source-line-no">6682</span><span id="line-6682"> region = HBaseTestingUtil.createRegionAndWAL(info, path, TEST_UTIL.getConfiguration(),</span>
<span class="source-line-no">6683</span><span id="line-6683"> tableDescriptor);</span>
<span class="source-line-no">6684</span><span id="line-6684"> Put put = new Put(Bytes.toBytes("a-b-0-0"));</span>
<span class="source-line-no">6685</span><span id="line-6685"> put.addColumn(fam1, qual1, Bytes.toBytes("c1-value"));</span>
<span class="source-line-no">6686</span><span id="line-6686"> region.put(put);</span>
<span class="source-line-no">6687</span><span id="line-6687"> region.flush(true);</span>
<span class="source-line-no">6688</span><span id="line-6688"> HStore store = region.getStore(fam1);</span>
<span class="source-line-no">6689</span><span id="line-6689"> Collection&lt;HStoreFile&gt; storefiles = store.getStorefiles();</span>
<span class="source-line-no">6690</span><span id="line-6690"> for (HStoreFile sf : storefiles) {</span>
<span class="source-line-no">6691</span><span id="line-6691"> assertFalse("Tags should not be present ",</span>
<span class="source-line-no">6692</span><span id="line-6692"> sf.getReader().getHFileReader().getFileContext().isIncludesTags());</span>
<span class="source-line-no">6693</span><span id="line-6693"> }</span>
<span class="source-line-no">6694</span><span id="line-6694"> }</span>
<span class="source-line-no">6695</span><span id="line-6695"></span>
<span class="source-line-no">6696</span><span id="line-6696"> /**</span>
<span class="source-line-no">6697</span><span id="line-6697"> * Utility method to setup a WAL mock.</span>
<span class="source-line-no">6698</span><span id="line-6698"> * &lt;p/&gt;</span>
<span class="source-line-no">6699</span><span id="line-6699"> * Needs to do the bit where we close latch on the WALKeyImpl on append else test hangs.</span>
<span class="source-line-no">6700</span><span id="line-6700"> * @return a mock WAL</span>
<span class="source-line-no">6701</span><span id="line-6701"> */</span>
<span class="source-line-no">6702</span><span id="line-6702"> private WAL mockWAL() throws IOException {</span>
<span class="source-line-no">6703</span><span id="line-6703"> WAL wal = mock(WAL.class);</span>
<span class="source-line-no">6704</span><span id="line-6704"> when(wal.appendData(any(RegionInfo.class), any(WALKeyImpl.class), any(WALEdit.class)))</span>
<span class="source-line-no">6705</span><span id="line-6705"> .thenAnswer(new Answer&lt;Long&gt;() {</span>
<span class="source-line-no">6706</span><span id="line-6706"> @Override</span>
<span class="source-line-no">6707</span><span id="line-6707"> public Long answer(InvocationOnMock invocation) throws Throwable {</span>
<span class="source-line-no">6708</span><span id="line-6708"> WALKeyImpl key = invocation.getArgument(1);</span>
<span class="source-line-no">6709</span><span id="line-6709"> MultiVersionConcurrencyControl.WriteEntry we = key.getMvcc().begin();</span>
<span class="source-line-no">6710</span><span id="line-6710"> key.setWriteEntry(we);</span>
<span class="source-line-no">6711</span><span id="line-6711"> return 1L;</span>
<span class="source-line-no">6712</span><span id="line-6712"> }</span>
<span class="source-line-no">6713</span><span id="line-6713"> });</span>
<span class="source-line-no">6714</span><span id="line-6714"> when(wal.appendMarker(any(RegionInfo.class), any(WALKeyImpl.class), any(WALEdit.class)))</span>
<span class="source-line-no">6715</span><span id="line-6715"> .thenAnswer(new Answer&lt;Long&gt;() {</span>
<span class="source-line-no">6716</span><span id="line-6716"> @Override</span>
<span class="source-line-no">6717</span><span id="line-6717"> public Long answer(InvocationOnMock invocation) throws Throwable {</span>
<span class="source-line-no">6718</span><span id="line-6718"> WALKeyImpl key = invocation.getArgument(1);</span>
<span class="source-line-no">6719</span><span id="line-6719"> MultiVersionConcurrencyControl.WriteEntry we = key.getMvcc().begin();</span>
<span class="source-line-no">6720</span><span id="line-6720"> key.setWriteEntry(we);</span>
<span class="source-line-no">6721</span><span id="line-6721"> return 1L;</span>
<span class="source-line-no">6722</span><span id="line-6722"> }</span>
<span class="source-line-no">6723</span><span id="line-6723"> });</span>
<span class="source-line-no">6724</span><span id="line-6724"> return wal;</span>
<span class="source-line-no">6725</span><span id="line-6725"> }</span>
<span class="source-line-no">6726</span><span id="line-6726"></span>
<span class="source-line-no">6727</span><span id="line-6727"> @Test</span>
<span class="source-line-no">6728</span><span id="line-6728"> public void testCloseRegionWrittenToWAL() throws Exception {</span>
<span class="source-line-no">6729</span><span id="line-6729"> Path rootDir = new Path(dir + name.getMethodName());</span>
<span class="source-line-no">6730</span><span id="line-6730"> CommonFSUtils.setRootDir(TEST_UTIL.getConfiguration(), rootDir);</span>
<span class="source-line-no">6731</span><span id="line-6731"></span>
<span class="source-line-no">6732</span><span id="line-6732"> final ServerName serverName = ServerName.valueOf("testCloseRegionWrittenToWAL", 100, 42);</span>
<span class="source-line-no">6733</span><span id="line-6733"> final RegionServerServices rss = spy(TEST_UTIL.createMockRegionServerService(serverName));</span>
<span class="source-line-no">6734</span><span id="line-6734"></span>
<span class="source-line-no">6735</span><span id="line-6735"> TableDescriptor htd = TableDescriptorBuilder.newBuilder(TableName.valueOf(name.getMethodName()))</span>
<span class="source-line-no">6736</span><span id="line-6736"> .setColumnFamily(ColumnFamilyDescriptorBuilder.of(fam1))</span>
<span class="source-line-no">6737</span><span id="line-6737"> .setColumnFamily(ColumnFamilyDescriptorBuilder.of(fam2)).build();</span>
<span class="source-line-no">6738</span><span id="line-6738"> RegionInfo hri = RegionInfoBuilder.newBuilder(htd.getTableName()).build();</span>
<span class="source-line-no">6739</span><span id="line-6739"></span>
<span class="source-line-no">6740</span><span id="line-6740"> ArgumentCaptor&lt;WALEdit&gt; editCaptor = ArgumentCaptor.forClass(WALEdit.class);</span>
<span class="source-line-no">6741</span><span id="line-6741"></span>
<span class="source-line-no">6742</span><span id="line-6742"> // capture append() calls</span>
<span class="source-line-no">6743</span><span id="line-6743"> WAL wal = mockWAL();</span>
<span class="source-line-no">6744</span><span id="line-6744"> when(rss.getWAL(any(RegionInfo.class))).thenReturn(wal);</span>
<span class="source-line-no">6745</span><span id="line-6745"></span>
<span class="source-line-no">6746</span><span id="line-6746"> // create the region</span>
<span class="source-line-no">6747</span><span id="line-6747"> region = HBaseTestingUtil.createRegionAndWAL(hri, rootDir, CONF, htd);</span>
<span class="source-line-no">6748</span><span id="line-6748"> HBaseTestingUtil.closeRegionAndWAL(region);</span>
<span class="source-line-no">6749</span><span id="line-6749"> region = null;</span>
<span class="source-line-no">6750</span><span id="line-6750"> // open the region first and then close it</span>
<span class="source-line-no">6751</span><span id="line-6751"> HRegion.openHRegion(hri, htd, rss.getWAL(hri), TEST_UTIL.getConfiguration(), rss, null).close();</span>
<span class="source-line-no">6752</span><span id="line-6752"></span>
<span class="source-line-no">6753</span><span id="line-6753"> // 2 times, one for region open, the other close region</span>
<span class="source-line-no">6754</span><span id="line-6754"> verify(wal, times(2)).appendMarker(any(RegionInfo.class), (WALKeyImpl) any(WALKeyImpl.class),</span>
<span class="source-line-no">6755</span><span id="line-6755"> editCaptor.capture());</span>
<span class="source-line-no">6756</span><span id="line-6756"></span>
<span class="source-line-no">6757</span><span id="line-6757"> WALEdit edit = editCaptor.getAllValues().get(1);</span>
<span class="source-line-no">6758</span><span id="line-6758"> assertNotNull(edit);</span>
<span class="source-line-no">6759</span><span id="line-6759"> assertNotNull(edit.getCells());</span>
<span class="source-line-no">6760</span><span id="line-6760"> assertEquals(1, edit.getCells().size());</span>
<span class="source-line-no">6761</span><span id="line-6761"> RegionEventDescriptor desc = WALEdit.getRegionEventDescriptor(edit.getCells().get(0));</span>
<span class="source-line-no">6762</span><span id="line-6762"> assertNotNull(desc);</span>
<span class="source-line-no">6763</span><span id="line-6763"></span>
<span class="source-line-no">6764</span><span id="line-6764"> LOG.info("RegionEventDescriptor from WAL: " + desc);</span>
<span class="source-line-no">6765</span><span id="line-6765"></span>
<span class="source-line-no">6766</span><span id="line-6766"> assertEquals(RegionEventDescriptor.EventType.REGION_CLOSE, desc.getEventType());</span>
<span class="source-line-no">6767</span><span id="line-6767"> assertTrue(Bytes.equals(desc.getTableName().toByteArray(), htd.getTableName().toBytes()));</span>
<span class="source-line-no">6768</span><span id="line-6768"> assertTrue(</span>
<span class="source-line-no">6769</span><span id="line-6769"> Bytes.equals(desc.getEncodedRegionName().toByteArray(), hri.getEncodedNameAsBytes()));</span>
<span class="source-line-no">6770</span><span id="line-6770"> assertTrue(desc.getLogSequenceNumber() &gt; 0);</span>
<span class="source-line-no">6771</span><span id="line-6771"> assertEquals(serverName, ProtobufUtil.toServerName(desc.getServer()));</span>
<span class="source-line-no">6772</span><span id="line-6772"> assertEquals(2, desc.getStoresCount());</span>
<span class="source-line-no">6773</span><span id="line-6773"></span>
<span class="source-line-no">6774</span><span id="line-6774"> StoreDescriptor store = desc.getStores(0);</span>
<span class="source-line-no">6775</span><span id="line-6775"> assertTrue(Bytes.equals(store.getFamilyName().toByteArray(), fam1));</span>
<span class="source-line-no">6776</span><span id="line-6776"> assertEquals(store.getStoreHomeDir(), Bytes.toString(fam1));</span>
<span class="source-line-no">6777</span><span id="line-6777"> assertEquals(0, store.getStoreFileCount()); // no store files</span>
<span class="source-line-no">6778</span><span id="line-6778"></span>
<span class="source-line-no">6779</span><span id="line-6779"> store = desc.getStores(1);</span>
<span class="source-line-no">6780</span><span id="line-6780"> assertTrue(Bytes.equals(store.getFamilyName().toByteArray(), fam2));</span>
<span class="source-line-no">6781</span><span id="line-6781"> assertEquals(store.getStoreHomeDir(), Bytes.toString(fam2));</span>
<span class="source-line-no">6782</span><span id="line-6782"> assertEquals(0, store.getStoreFileCount()); // no store files</span>
<span class="source-line-no">6783</span><span id="line-6783"> }</span>
<span class="source-line-no">6784</span><span id="line-6784"></span>
<span class="source-line-no">6785</span><span id="line-6785"> /**</span>
<span class="source-line-no">6786</span><span id="line-6786"> * Test RegionTooBusyException thrown when region is busy</span>
<span class="source-line-no">6787</span><span id="line-6787"> */</span>
<span class="source-line-no">6788</span><span id="line-6788"> @Test</span>
<span class="source-line-no">6789</span><span id="line-6789"> public void testRegionTooBusy() throws IOException {</span>
<span class="source-line-no">6790</span><span id="line-6790"> byte[] family = Bytes.toBytes("family");</span>
<span class="source-line-no">6791</span><span id="line-6791"> long defaultBusyWaitDuration =</span>
<span class="source-line-no">6792</span><span id="line-6792"> CONF.getLong("hbase.busy.wait.duration", HRegion.DEFAULT_BUSY_WAIT_DURATION);</span>
<span class="source-line-no">6793</span><span id="line-6793"> CONF.setLong("hbase.busy.wait.duration", 1000);</span>
<span class="source-line-no">6794</span><span id="line-6794"> region = initHRegion(tableName, method, CONF, family);</span>
<span class="source-line-no">6795</span><span id="line-6795"> final AtomicBoolean stopped = new AtomicBoolean(true);</span>
<span class="source-line-no">6796</span><span id="line-6796"> Thread t = new Thread(new Runnable() {</span>
<span class="source-line-no">6797</span><span id="line-6797"> @Override</span>
<span class="source-line-no">6798</span><span id="line-6798"> public void run() {</span>
<span class="source-line-no">6799</span><span id="line-6799"> try {</span>
<span class="source-line-no">6800</span><span id="line-6800"> region.lock.writeLock().lock();</span>
<span class="source-line-no">6801</span><span id="line-6801"> stopped.set(false);</span>
<span class="source-line-no">6802</span><span id="line-6802"> while (!stopped.get()) {</span>
<span class="source-line-no">6803</span><span id="line-6803"> Thread.sleep(100);</span>
<span class="source-line-no">6804</span><span id="line-6804"> }</span>
<span class="source-line-no">6805</span><span id="line-6805"> } catch (InterruptedException ie) {</span>
<span class="source-line-no">6806</span><span id="line-6806"> } finally {</span>
<span class="source-line-no">6807</span><span id="line-6807"> region.lock.writeLock().unlock();</span>
<span class="source-line-no">6808</span><span id="line-6808"> }</span>
<span class="source-line-no">6809</span><span id="line-6809"> }</span>
<span class="source-line-no">6810</span><span id="line-6810"> });</span>
<span class="source-line-no">6811</span><span id="line-6811"> t.start();</span>
<span class="source-line-no">6812</span><span id="line-6812"> Get get = new Get(row);</span>
<span class="source-line-no">6813</span><span id="line-6813"> try {</span>
<span class="source-line-no">6814</span><span id="line-6814"> while (stopped.get()) {</span>
<span class="source-line-no">6815</span><span id="line-6815"> Thread.sleep(100);</span>
<span class="source-line-no">6816</span><span id="line-6816"> }</span>
<span class="source-line-no">6817</span><span id="line-6817"> region.get(get);</span>
<span class="source-line-no">6818</span><span id="line-6818"> fail("Should throw RegionTooBusyException");</span>
<span class="source-line-no">6819</span><span id="line-6819"> } catch (InterruptedException ie) {</span>
<span class="source-line-no">6820</span><span id="line-6820"> fail("test interrupted");</span>
<span class="source-line-no">6821</span><span id="line-6821"> } catch (RegionTooBusyException e) {</span>
<span class="source-line-no">6822</span><span id="line-6822"> // Good, expected</span>
<span class="source-line-no">6823</span><span id="line-6823"> } finally {</span>
<span class="source-line-no">6824</span><span id="line-6824"> stopped.set(true);</span>
<span class="source-line-no">6825</span><span id="line-6825"> try {</span>
<span class="source-line-no">6826</span><span id="line-6826"> t.join();</span>
<span class="source-line-no">6827</span><span id="line-6827"> } catch (Throwable e) {</span>
<span class="source-line-no">6828</span><span id="line-6828"> }</span>
<span class="source-line-no">6829</span><span id="line-6829"></span>
<span class="source-line-no">6830</span><span id="line-6830"> HBaseTestingUtil.closeRegionAndWAL(region);</span>
<span class="source-line-no">6831</span><span id="line-6831"> region = null;</span>
<span class="source-line-no">6832</span><span id="line-6832"> CONF.setLong("hbase.busy.wait.duration", defaultBusyWaitDuration);</span>
<span class="source-line-no">6833</span><span id="line-6833"> }</span>
<span class="source-line-no">6834</span><span id="line-6834"> }</span>
<span class="source-line-no">6835</span><span id="line-6835"></span>
<span class="source-line-no">6836</span><span id="line-6836"> @Test</span>
<span class="source-line-no">6837</span><span id="line-6837"> public void testCellTTLs() throws IOException {</span>
<span class="source-line-no">6838</span><span id="line-6838"> IncrementingEnvironmentEdge edge = new IncrementingEnvironmentEdge();</span>
<span class="source-line-no">6839</span><span id="line-6839"> EnvironmentEdgeManager.injectEdge(edge);</span>
<span class="source-line-no">6840</span><span id="line-6840"></span>
<span class="source-line-no">6841</span><span id="line-6841"> final byte[] row = Bytes.toBytes("testRow");</span>
<span class="source-line-no">6842</span><span id="line-6842"> final byte[] q1 = Bytes.toBytes("q1");</span>
<span class="source-line-no">6843</span><span id="line-6843"> final byte[] q2 = Bytes.toBytes("q2");</span>
<span class="source-line-no">6844</span><span id="line-6844"> final byte[] q3 = Bytes.toBytes("q3");</span>
<span class="source-line-no">6845</span><span id="line-6845"> final byte[] q4 = Bytes.toBytes("q4");</span>
<span class="source-line-no">6846</span><span id="line-6846"></span>
<span class="source-line-no">6847</span><span id="line-6847"> // 10 seconds</span>
<span class="source-line-no">6848</span><span id="line-6848"> TableDescriptor tableDescriptor =</span>
<span class="source-line-no">6849</span><span id="line-6849"> TableDescriptorBuilder.newBuilder(TableName.valueOf(name.getMethodName()))</span>
<span class="source-line-no">6850</span><span id="line-6850"> .setColumnFamily(ColumnFamilyDescriptorBuilder.newBuilder(fam1).setTimeToLive(10).build())</span>
<span class="source-line-no">6851</span><span id="line-6851"> .build();</span>
<span class="source-line-no">6852</span><span id="line-6852"></span>
<span class="source-line-no">6853</span><span id="line-6853"> Configuration conf = new Configuration(TEST_UTIL.getConfiguration());</span>
<span class="source-line-no">6854</span><span id="line-6854"> conf.setInt(HFile.FORMAT_VERSION_KEY, HFile.MIN_FORMAT_VERSION_WITH_TAGS);</span>
<span class="source-line-no">6855</span><span id="line-6855"></span>
<span class="source-line-no">6856</span><span id="line-6856"> region = HBaseTestingUtil.createRegionAndWAL(</span>
<span class="source-line-no">6857</span><span id="line-6857"> RegionInfoBuilder.newBuilder(tableDescriptor.getTableName()).build(),</span>
<span class="source-line-no">6858</span><span id="line-6858"> TEST_UTIL.getDataTestDir(), conf, tableDescriptor);</span>
<span class="source-line-no">6859</span><span id="line-6859"> assertNotNull(region);</span>
<span class="source-line-no">6860</span><span id="line-6860"> long now = EnvironmentEdgeManager.currentTime();</span>
<span class="source-line-no">6861</span><span id="line-6861"> // Add a cell that will expire in 5 seconds via cell TTL</span>
<span class="source-line-no">6862</span><span id="line-6862"> region.put(new Put(row).add(new KeyValue(row, fam1, q1, now, HConstants.EMPTY_BYTE_ARRAY,</span>
<span class="source-line-no">6863</span><span id="line-6863"> new ArrayBackedTag[] {</span>
<span class="source-line-no">6864</span><span id="line-6864"> // TTL tags specify ts in milliseconds</span>
<span class="source-line-no">6865</span><span id="line-6865"> new ArrayBackedTag(TagType.TTL_TAG_TYPE, Bytes.toBytes(5000L)) })));</span>
<span class="source-line-no">6866</span><span id="line-6866"> // Add a cell that will expire after 10 seconds via family setting</span>
<span class="source-line-no">6867</span><span id="line-6867"> region.put(new Put(row).addColumn(fam1, q2, now, HConstants.EMPTY_BYTE_ARRAY));</span>
<span class="source-line-no">6868</span><span id="line-6868"> // Add a cell that will expire in 15 seconds via cell TTL</span>
<span class="source-line-no">6869</span><span id="line-6869"> region.put(new Put(row).add(new KeyValue(row, fam1, q3, now + 10000 - 1,</span>
<span class="source-line-no">6870</span><span id="line-6870"> HConstants.EMPTY_BYTE_ARRAY, new ArrayBackedTag[] {</span>
<span class="source-line-no">6871</span><span id="line-6871"> // TTL tags specify ts in milliseconds</span>
<span class="source-line-no">6872</span><span id="line-6872"> new ArrayBackedTag(TagType.TTL_TAG_TYPE, Bytes.toBytes(5000L)) })));</span>
<span class="source-line-no">6873</span><span id="line-6873"> // Add a cell that will expire in 20 seconds via family setting</span>
<span class="source-line-no">6874</span><span id="line-6874"> region.put(new Put(row).addColumn(fam1, q4, now + 10000 - 1, HConstants.EMPTY_BYTE_ARRAY));</span>
<span class="source-line-no">6875</span><span id="line-6875"></span>
<span class="source-line-no">6876</span><span id="line-6876"> // Flush so we are sure store scanning gets this right</span>
<span class="source-line-no">6877</span><span id="line-6877"> region.flush(true);</span>
<span class="source-line-no">6878</span><span id="line-6878"></span>
<span class="source-line-no">6879</span><span id="line-6879"> // A query at time T+0 should return all cells</span>
<span class="source-line-no">6880</span><span id="line-6880"> Result r = region.get(new Get(row));</span>
<span class="source-line-no">6881</span><span id="line-6881"> assertNotNull(r.getValue(fam1, q1));</span>
<span class="source-line-no">6882</span><span id="line-6882"> assertNotNull(r.getValue(fam1, q2));</span>
<span class="source-line-no">6883</span><span id="line-6883"> assertNotNull(r.getValue(fam1, q3));</span>
<span class="source-line-no">6884</span><span id="line-6884"> assertNotNull(r.getValue(fam1, q4));</span>
<span class="source-line-no">6885</span><span id="line-6885"></span>
<span class="source-line-no">6886</span><span id="line-6886"> // Increment time to T+5 seconds</span>
<span class="source-line-no">6887</span><span id="line-6887"> edge.incrementTime(5000);</span>
<span class="source-line-no">6888</span><span id="line-6888"></span>
<span class="source-line-no">6889</span><span id="line-6889"> r = region.get(new Get(row));</span>
<span class="source-line-no">6890</span><span id="line-6890"> assertNull(r.getValue(fam1, q1));</span>
<span class="source-line-no">6891</span><span id="line-6891"> assertNotNull(r.getValue(fam1, q2));</span>
<span class="source-line-no">6892</span><span id="line-6892"> assertNotNull(r.getValue(fam1, q3));</span>
<span class="source-line-no">6893</span><span id="line-6893"> assertNotNull(r.getValue(fam1, q4));</span>
<span class="source-line-no">6894</span><span id="line-6894"></span>
<span class="source-line-no">6895</span><span id="line-6895"> // Increment time to T+10 seconds</span>
<span class="source-line-no">6896</span><span id="line-6896"> edge.incrementTime(5000);</span>
<span class="source-line-no">6897</span><span id="line-6897"></span>
<span class="source-line-no">6898</span><span id="line-6898"> r = region.get(new Get(row));</span>
<span class="source-line-no">6899</span><span id="line-6899"> assertNull(r.getValue(fam1, q1));</span>
<span class="source-line-no">6900</span><span id="line-6900"> assertNull(r.getValue(fam1, q2));</span>
<span class="source-line-no">6901</span><span id="line-6901"> assertNotNull(r.getValue(fam1, q3));</span>
<span class="source-line-no">6902</span><span id="line-6902"> assertNotNull(r.getValue(fam1, q4));</span>
<span class="source-line-no">6903</span><span id="line-6903"></span>
<span class="source-line-no">6904</span><span id="line-6904"> // Increment time to T+15 seconds</span>
<span class="source-line-no">6905</span><span id="line-6905"> edge.incrementTime(5000);</span>
<span class="source-line-no">6906</span><span id="line-6906"></span>
<span class="source-line-no">6907</span><span id="line-6907"> r = region.get(new Get(row));</span>
<span class="source-line-no">6908</span><span id="line-6908"> assertNull(r.getValue(fam1, q1));</span>
<span class="source-line-no">6909</span><span id="line-6909"> assertNull(r.getValue(fam1, q2));</span>
<span class="source-line-no">6910</span><span id="line-6910"> assertNull(r.getValue(fam1, q3));</span>
<span class="source-line-no">6911</span><span id="line-6911"> assertNotNull(r.getValue(fam1, q4));</span>
<span class="source-line-no">6912</span><span id="line-6912"></span>
<span class="source-line-no">6913</span><span id="line-6913"> // Increment time to T+20 seconds</span>
<span class="source-line-no">6914</span><span id="line-6914"> edge.incrementTime(10000);</span>
<span class="source-line-no">6915</span><span id="line-6915"></span>
<span class="source-line-no">6916</span><span id="line-6916"> r = region.get(new Get(row));</span>
<span class="source-line-no">6917</span><span id="line-6917"> assertNull(r.getValue(fam1, q1));</span>
<span class="source-line-no">6918</span><span id="line-6918"> assertNull(r.getValue(fam1, q2));</span>
<span class="source-line-no">6919</span><span id="line-6919"> assertNull(r.getValue(fam1, q3));</span>
<span class="source-line-no">6920</span><span id="line-6920"> assertNull(r.getValue(fam1, q4));</span>
<span class="source-line-no">6921</span><span id="line-6921"></span>
<span class="source-line-no">6922</span><span id="line-6922"> // Fun with disappearing increments</span>
<span class="source-line-no">6923</span><span id="line-6923"></span>
<span class="source-line-no">6924</span><span id="line-6924"> // Start at 1</span>
<span class="source-line-no">6925</span><span id="line-6925"> region.put(new Put(row).addColumn(fam1, q1, Bytes.toBytes(1L)));</span>
<span class="source-line-no">6926</span><span id="line-6926"> r = region.get(new Get(row));</span>
<span class="source-line-no">6927</span><span id="line-6927"> byte[] val = r.getValue(fam1, q1);</span>
<span class="source-line-no">6928</span><span id="line-6928"> assertNotNull(val);</span>
<span class="source-line-no">6929</span><span id="line-6929"> assertEquals(1L, Bytes.toLong(val));</span>
<span class="source-line-no">6930</span><span id="line-6930"></span>
<span class="source-line-no">6931</span><span id="line-6931"> // Increment with a TTL of 5 seconds</span>
<span class="source-line-no">6932</span><span id="line-6932"> Increment incr = new Increment(row).addColumn(fam1, q1, 1L);</span>
<span class="source-line-no">6933</span><span id="line-6933"> incr.setTTL(5000);</span>
<span class="source-line-no">6934</span><span id="line-6934"> region.increment(incr); // 2</span>
<span class="source-line-no">6935</span><span id="line-6935"></span>
<span class="source-line-no">6936</span><span id="line-6936"> // New value should be 2</span>
<span class="source-line-no">6937</span><span id="line-6937"> r = region.get(new Get(row));</span>
<span class="source-line-no">6938</span><span id="line-6938"> val = r.getValue(fam1, q1);</span>
<span class="source-line-no">6939</span><span id="line-6939"> assertNotNull(val);</span>
<span class="source-line-no">6940</span><span id="line-6940"> assertEquals(2L, Bytes.toLong(val));</span>
<span class="source-line-no">6941</span><span id="line-6941"></span>
<span class="source-line-no">6942</span><span id="line-6942"> // Increment time to T+25 seconds</span>
<span class="source-line-no">6943</span><span id="line-6943"> edge.incrementTime(5000);</span>
<span class="source-line-no">6944</span><span id="line-6944"></span>
<span class="source-line-no">6945</span><span id="line-6945"> // Value should be back to 1</span>
<span class="source-line-no">6946</span><span id="line-6946"> r = region.get(new Get(row));</span>
<span class="source-line-no">6947</span><span id="line-6947"> val = r.getValue(fam1, q1);</span>
<span class="source-line-no">6948</span><span id="line-6948"> assertNotNull(val);</span>
<span class="source-line-no">6949</span><span id="line-6949"> assertEquals(1L, Bytes.toLong(val));</span>
<span class="source-line-no">6950</span><span id="line-6950"></span>
<span class="source-line-no">6951</span><span id="line-6951"> // Increment time to T+30 seconds</span>
<span class="source-line-no">6952</span><span id="line-6952"> edge.incrementTime(5000);</span>
<span class="source-line-no">6953</span><span id="line-6953"></span>
<span class="source-line-no">6954</span><span id="line-6954"> // Original value written at T+20 should be gone now via family TTL</span>
<span class="source-line-no">6955</span><span id="line-6955"> r = region.get(new Get(row));</span>
<span class="source-line-no">6956</span><span id="line-6956"> assertNull(r.getValue(fam1, q1));</span>
<span class="source-line-no">6957</span><span id="line-6957"> }</span>
<span class="source-line-no">6958</span><span id="line-6958"></span>
<span class="source-line-no">6959</span><span id="line-6959"> @Test</span>
<span class="source-line-no">6960</span><span id="line-6960"> public void testTTLsUsingSmallHeartBeatCells() throws IOException {</span>
<span class="source-line-no">6961</span><span id="line-6961"> IncrementingEnvironmentEdge edge = new IncrementingEnvironmentEdge();</span>
<span class="source-line-no">6962</span><span id="line-6962"> EnvironmentEdgeManager.injectEdge(edge);</span>
<span class="source-line-no">6963</span><span id="line-6963"></span>
<span class="source-line-no">6964</span><span id="line-6964"> final byte[] row = Bytes.toBytes("testRow");</span>
<span class="source-line-no">6965</span><span id="line-6965"> final byte[] q1 = Bytes.toBytes("q1");</span>
<span class="source-line-no">6966</span><span id="line-6966"> final byte[] q2 = Bytes.toBytes("q2");</span>
<span class="source-line-no">6967</span><span id="line-6967"> final byte[] q3 = Bytes.toBytes("q3");</span>
<span class="source-line-no">6968</span><span id="line-6968"> final byte[] q4 = Bytes.toBytes("q4");</span>
<span class="source-line-no">6969</span><span id="line-6969"> final byte[] q5 = Bytes.toBytes("q5");</span>
<span class="source-line-no">6970</span><span id="line-6970"> final byte[] q6 = Bytes.toBytes("q6");</span>
<span class="source-line-no">6971</span><span id="line-6971"> final byte[] q7 = Bytes.toBytes("q7");</span>
<span class="source-line-no">6972</span><span id="line-6972"> final byte[] q8 = Bytes.toBytes("q8");</span>
<span class="source-line-no">6973</span><span id="line-6973"></span>
<span class="source-line-no">6974</span><span id="line-6974"> // 10 seconds</span>
<span class="source-line-no">6975</span><span id="line-6975"> int ttlSecs = 10;</span>
<span class="source-line-no">6976</span><span id="line-6976"> TableDescriptor tableDescriptor =</span>
<span class="source-line-no">6977</span><span id="line-6977"> TableDescriptorBuilder.newBuilder(TableName.valueOf(name.getMethodName())).setColumnFamily(</span>
<span class="source-line-no">6978</span><span id="line-6978"> ColumnFamilyDescriptorBuilder.newBuilder(fam1).setTimeToLive(ttlSecs).build()).build();</span>
<span class="source-line-no">6979</span><span id="line-6979"></span>
<span class="source-line-no">6980</span><span id="line-6980"> Configuration conf = new Configuration(TEST_UTIL.getConfiguration());</span>
<span class="source-line-no">6981</span><span id="line-6981"> conf.setInt(HFile.FORMAT_VERSION_KEY, HFile.MIN_FORMAT_VERSION_WITH_TAGS);</span>
<span class="source-line-no">6982</span><span id="line-6982"> // using small heart beat cells</span>
<span class="source-line-no">6983</span><span id="line-6983"> conf.setLong(StoreScanner.HBASE_CELLS_SCANNED_PER_HEARTBEAT_CHECK, 2);</span>
<span class="source-line-no">6984</span><span id="line-6984"></span>
<span class="source-line-no">6985</span><span id="line-6985"> region = HBaseTestingUtil.createRegionAndWAL(</span>
<span class="source-line-no">6986</span><span id="line-6986"> RegionInfoBuilder.newBuilder(tableDescriptor.getTableName()).build(),</span>
<span class="source-line-no">6987</span><span id="line-6987"> TEST_UTIL.getDataTestDir(), conf, tableDescriptor);</span>
<span class="source-line-no">6988</span><span id="line-6988"> assertNotNull(region);</span>
<span class="source-line-no">6989</span><span id="line-6989"> long now = EnvironmentEdgeManager.currentTime();</span>
<span class="source-line-no">6990</span><span id="line-6990"> // Add a cell that will expire in 5 seconds via cell TTL</span>
<span class="source-line-no">6991</span><span id="line-6991"> region.put(new Put(row).addColumn(fam1, q1, now, HConstants.EMPTY_BYTE_ARRAY));</span>
<span class="source-line-no">6992</span><span id="line-6992"> region.put(new Put(row).addColumn(fam1, q2, now, HConstants.EMPTY_BYTE_ARRAY));</span>
<span class="source-line-no">6993</span><span id="line-6993"> region.put(new Put(row).addColumn(fam1, q3, now, HConstants.EMPTY_BYTE_ARRAY));</span>
<span class="source-line-no">6994</span><span id="line-6994"> // Add a cell that will expire after 10 seconds via family setting</span>
<span class="source-line-no">6995</span><span id="line-6995"> region</span>
<span class="source-line-no">6996</span><span id="line-6996"> .put(new Put(row).addColumn(fam1, q4, now + ttlSecs * 1000 + 1, HConstants.EMPTY_BYTE_ARRAY));</span>
<span class="source-line-no">6997</span><span id="line-6997"> region</span>
<span class="source-line-no">6998</span><span id="line-6998"> .put(new Put(row).addColumn(fam1, q5, now + ttlSecs * 1000 + 1, HConstants.EMPTY_BYTE_ARRAY));</span>
<span class="source-line-no">6999</span><span id="line-6999"></span>
<span class="source-line-no">7000</span><span id="line-7000"> region.put(new Put(row).addColumn(fam1, q6, now, HConstants.EMPTY_BYTE_ARRAY));</span>
<span class="source-line-no">7001</span><span id="line-7001"> region.put(new Put(row).addColumn(fam1, q7, now, HConstants.EMPTY_BYTE_ARRAY));</span>
<span class="source-line-no">7002</span><span id="line-7002"> region</span>
<span class="source-line-no">7003</span><span id="line-7003"> .put(new Put(row).addColumn(fam1, q8, now + ttlSecs * 1000 + 1, HConstants.EMPTY_BYTE_ARRAY));</span>
<span class="source-line-no">7004</span><span id="line-7004"></span>
<span class="source-line-no">7005</span><span id="line-7005"> // Flush so we are sure store scanning gets this right</span>
<span class="source-line-no">7006</span><span id="line-7006"> region.flush(true);</span>
<span class="source-line-no">7007</span><span id="line-7007"></span>
<span class="source-line-no">7008</span><span id="line-7008"> // A query at time T+0 should return all cells</span>
<span class="source-line-no">7009</span><span id="line-7009"> checkScan(8);</span>
<span class="source-line-no">7010</span><span id="line-7010"> region.delete(new Delete(row).addColumn(fam1, q8));</span>
<span class="source-line-no">7011</span><span id="line-7011"></span>
<span class="source-line-no">7012</span><span id="line-7012"> // Increment time to T+ttlSecs seconds</span>
<span class="source-line-no">7013</span><span id="line-7013"> edge.incrementTime(ttlSecs * 1000);</span>
<span class="source-line-no">7014</span><span id="line-7014"> checkScan(2);</span>
<span class="source-line-no">7015</span><span id="line-7015"> }</span>
<span class="source-line-no">7016</span><span id="line-7016"></span>
<span class="source-line-no">7017</span><span id="line-7017"> private void checkScan(int expectCellSize) throws IOException {</span>
<span class="source-line-no">7018</span><span id="line-7018"> Scan s = new Scan().withStartRow(row);</span>
<span class="source-line-no">7019</span><span id="line-7019"> ScannerContext.Builder contextBuilder = ScannerContext.newBuilder(true);</span>
<span class="source-line-no">7020</span><span id="line-7020"> ScannerContext scannerContext = contextBuilder.build();</span>
<span class="source-line-no">7021</span><span id="line-7021"> try (RegionScanner scanner = region.getScanner(s)) {</span>
<span class="source-line-no">7022</span><span id="line-7022"> List&lt;Cell&gt; kvs = new ArrayList&lt;&gt;();</span>
<span class="source-line-no">7023</span><span id="line-7023"> scanner.next(kvs, scannerContext);</span>
<span class="source-line-no">7024</span><span id="line-7024"> assertEquals(expectCellSize, kvs.size());</span>
<span class="source-line-no">7025</span><span id="line-7025"> }</span>
<span class="source-line-no">7026</span><span id="line-7026"> }</span>
<span class="source-line-no">7027</span><span id="line-7027"></span>
<span class="source-line-no">7028</span><span id="line-7028"> @Test</span>
<span class="source-line-no">7029</span><span id="line-7029"> public void testIncrementTimestampsAreMonotonic() throws IOException {</span>
<span class="source-line-no">7030</span><span id="line-7030"> region = initHRegion(tableName, method, CONF, fam1);</span>
<span class="source-line-no">7031</span><span id="line-7031"> ManualEnvironmentEdge edge = new ManualEnvironmentEdge();</span>
<span class="source-line-no">7032</span><span id="line-7032"> EnvironmentEdgeManager.injectEdge(edge);</span>
<span class="source-line-no">7033</span><span id="line-7033"></span>
<span class="source-line-no">7034</span><span id="line-7034"> edge.setValue(10);</span>
<span class="source-line-no">7035</span><span id="line-7035"> Increment inc = new Increment(row);</span>
<span class="source-line-no">7036</span><span id="line-7036"> inc.setDurability(Durability.SKIP_WAL);</span>
<span class="source-line-no">7037</span><span id="line-7037"> inc.addColumn(fam1, qual1, 1L);</span>
<span class="source-line-no">7038</span><span id="line-7038"> region.increment(inc);</span>
<span class="source-line-no">7039</span><span id="line-7039"></span>
<span class="source-line-no">7040</span><span id="line-7040"> Result result = region.get(new Get(row));</span>
<span class="source-line-no">7041</span><span id="line-7041"> Cell c = result.getColumnLatestCell(fam1, qual1);</span>
<span class="source-line-no">7042</span><span id="line-7042"> assertNotNull(c);</span>
<span class="source-line-no">7043</span><span id="line-7043"> assertEquals(10L, c.getTimestamp());</span>
<span class="source-line-no">7044</span><span id="line-7044"></span>
<span class="source-line-no">7045</span><span id="line-7045"> edge.setValue(1); // clock goes back</span>
<span class="source-line-no">7046</span><span id="line-7046"> region.increment(inc);</span>
<span class="source-line-no">7047</span><span id="line-7047"> result = region.get(new Get(row));</span>
<span class="source-line-no">7048</span><span id="line-7048"> c = result.getColumnLatestCell(fam1, qual1);</span>
<span class="source-line-no">7049</span><span id="line-7049"> assertEquals(11L, c.getTimestamp());</span>
<span class="source-line-no">7050</span><span id="line-7050"> assertEquals(2L, Bytes.toLong(c.getValueArray(), c.getValueOffset(), c.getValueLength()));</span>
<span class="source-line-no">7051</span><span id="line-7051"> }</span>
<span class="source-line-no">7052</span><span id="line-7052"></span>
<span class="source-line-no">7053</span><span id="line-7053"> @Test</span>
<span class="source-line-no">7054</span><span id="line-7054"> public void testAppendTimestampsAreMonotonic() throws IOException {</span>
<span class="source-line-no">7055</span><span id="line-7055"> region = initHRegion(tableName, method, CONF, fam1);</span>
<span class="source-line-no">7056</span><span id="line-7056"> ManualEnvironmentEdge edge = new ManualEnvironmentEdge();</span>
<span class="source-line-no">7057</span><span id="line-7057"> EnvironmentEdgeManager.injectEdge(edge);</span>
<span class="source-line-no">7058</span><span id="line-7058"></span>
<span class="source-line-no">7059</span><span id="line-7059"> edge.setValue(10);</span>
<span class="source-line-no">7060</span><span id="line-7060"> Append a = new Append(row);</span>
<span class="source-line-no">7061</span><span id="line-7061"> a.setDurability(Durability.SKIP_WAL);</span>
<span class="source-line-no">7062</span><span id="line-7062"> a.addColumn(fam1, qual1, qual1);</span>
<span class="source-line-no">7063</span><span id="line-7063"> region.append(a);</span>
<span class="source-line-no">7064</span><span id="line-7064"></span>
<span class="source-line-no">7065</span><span id="line-7065"> Result result = region.get(new Get(row));</span>
<span class="source-line-no">7066</span><span id="line-7066"> Cell c = result.getColumnLatestCell(fam1, qual1);</span>
<span class="source-line-no">7067</span><span id="line-7067"> assertNotNull(c);</span>
<span class="source-line-no">7068</span><span id="line-7068"> assertEquals(10L, c.getTimestamp());</span>
<span class="source-line-no">7069</span><span id="line-7069"></span>
<span class="source-line-no">7070</span><span id="line-7070"> edge.setValue(1); // clock goes back</span>
<span class="source-line-no">7071</span><span id="line-7071"> region.append(a);</span>
<span class="source-line-no">7072</span><span id="line-7072"> result = region.get(new Get(row));</span>
<span class="source-line-no">7073</span><span id="line-7073"> c = result.getColumnLatestCell(fam1, qual1);</span>
<span class="source-line-no">7074</span><span id="line-7074"> assertEquals(11L, c.getTimestamp());</span>
<span class="source-line-no">7075</span><span id="line-7075"></span>
<span class="source-line-no">7076</span><span id="line-7076"> byte[] expected = new byte[qual1.length * 2];</span>
<span class="source-line-no">7077</span><span id="line-7077"> System.arraycopy(qual1, 0, expected, 0, qual1.length);</span>
<span class="source-line-no">7078</span><span id="line-7078"> System.arraycopy(qual1, 0, expected, qual1.length, qual1.length);</span>
<span class="source-line-no">7079</span><span id="line-7079"></span>
<span class="source-line-no">7080</span><span id="line-7080"> assertTrue(Bytes.equals(c.getValueArray(), c.getValueOffset(), c.getValueLength(), expected, 0,</span>
<span class="source-line-no">7081</span><span id="line-7081"> expected.length));</span>
<span class="source-line-no">7082</span><span id="line-7082"> }</span>
<span class="source-line-no">7083</span><span id="line-7083"></span>
<span class="source-line-no">7084</span><span id="line-7084"> @Test</span>
<span class="source-line-no">7085</span><span id="line-7085"> public void testCheckAndMutateTimestampsAreMonotonic() throws IOException {</span>
<span class="source-line-no">7086</span><span id="line-7086"> region = initHRegion(tableName, method, CONF, fam1);</span>
<span class="source-line-no">7087</span><span id="line-7087"> ManualEnvironmentEdge edge = new ManualEnvironmentEdge();</span>
<span class="source-line-no">7088</span><span id="line-7088"> EnvironmentEdgeManager.injectEdge(edge);</span>
<span class="source-line-no">7089</span><span id="line-7089"></span>
<span class="source-line-no">7090</span><span id="line-7090"> edge.setValue(10);</span>
<span class="source-line-no">7091</span><span id="line-7091"> Put p = new Put(row);</span>
<span class="source-line-no">7092</span><span id="line-7092"> p.setDurability(Durability.SKIP_WAL);</span>
<span class="source-line-no">7093</span><span id="line-7093"> p.addColumn(fam1, qual1, qual1);</span>
<span class="source-line-no">7094</span><span id="line-7094"> region.put(p);</span>
<span class="source-line-no">7095</span><span id="line-7095"></span>
<span class="source-line-no">7096</span><span id="line-7096"> Result result = region.get(new Get(row));</span>
<span class="source-line-no">7097</span><span id="line-7097"> Cell c = result.getColumnLatestCell(fam1, qual1);</span>
<span class="source-line-no">7098</span><span id="line-7098"> assertNotNull(c);</span>
<span class="source-line-no">7099</span><span id="line-7099"> assertEquals(10L, c.getTimestamp());</span>
<span class="source-line-no">7100</span><span id="line-7100"></span>
<span class="source-line-no">7101</span><span id="line-7101"> edge.setValue(1); // clock goes back</span>
<span class="source-line-no">7102</span><span id="line-7102"> p = new Put(row);</span>
<span class="source-line-no">7103</span><span id="line-7103"> p.setDurability(Durability.SKIP_WAL);</span>
<span class="source-line-no">7104</span><span id="line-7104"> p.addColumn(fam1, qual1, qual2);</span>
<span class="source-line-no">7105</span><span id="line-7105"> region.checkAndMutate(row, fam1, qual1, CompareOperator.EQUAL, new BinaryComparator(qual1), p);</span>
<span class="source-line-no">7106</span><span id="line-7106"> result = region.get(new Get(row));</span>
<span class="source-line-no">7107</span><span id="line-7107"> c = result.getColumnLatestCell(fam1, qual1);</span>
<span class="source-line-no">7108</span><span id="line-7108"> assertEquals(10L, c.getTimestamp());</span>
<span class="source-line-no">7109</span><span id="line-7109"></span>
<span class="source-line-no">7110</span><span id="line-7110"> assertTrue(Bytes.equals(c.getValueArray(), c.getValueOffset(), c.getValueLength(), qual2, 0,</span>
<span class="source-line-no">7111</span><span id="line-7111"> qual2.length));</span>
<span class="source-line-no">7112</span><span id="line-7112"> }</span>
<span class="source-line-no">7113</span><span id="line-7113"></span>
<span class="source-line-no">7114</span><span id="line-7114"> @Test</span>
<span class="source-line-no">7115</span><span id="line-7115"> public void testBatchMutateWithWrongRegionException() throws Exception {</span>
<span class="source-line-no">7116</span><span id="line-7116"> final byte[] a = Bytes.toBytes("a");</span>
<span class="source-line-no">7117</span><span id="line-7117"> final byte[] b = Bytes.toBytes("b");</span>
<span class="source-line-no">7118</span><span id="line-7118"> final byte[] c = Bytes.toBytes("c"); // exclusive</span>
<span class="source-line-no">7119</span><span id="line-7119"></span>
<span class="source-line-no">7120</span><span id="line-7120"> int prevLockTimeout = CONF.getInt("hbase.rowlock.wait.duration", 30000);</span>
<span class="source-line-no">7121</span><span id="line-7121"> CONF.setInt("hbase.rowlock.wait.duration", 1000);</span>
<span class="source-line-no">7122</span><span id="line-7122"> region = initHRegion(tableName, a, c, method, CONF, false, fam1);</span>
<span class="source-line-no">7123</span><span id="line-7123"></span>
<span class="source-line-no">7124</span><span id="line-7124"> Mutation[] mutations = new Mutation[] {</span>
<span class="source-line-no">7125</span><span id="line-7125"> new Put(a).add(CellBuilderFactory.create(CellBuilderType.SHALLOW_COPY).setRow(a)</span>
<span class="source-line-no">7126</span><span id="line-7126"> .setFamily(fam1).setTimestamp(HConstants.LATEST_TIMESTAMP).setType(Cell.Type.Put).build()),</span>
<span class="source-line-no">7127</span><span id="line-7127"> // this is outside the region boundary</span>
<span class="source-line-no">7128</span><span id="line-7128"> new Put(c).add(CellBuilderFactory.create(CellBuilderType.SHALLOW_COPY).setRow(c)</span>
<span class="source-line-no">7129</span><span id="line-7129"> .setFamily(fam1).setTimestamp(HConstants.LATEST_TIMESTAMP).setType(Type.Put).build()),</span>
<span class="source-line-no">7130</span><span id="line-7130"> new Put(b)</span>
<span class="source-line-no">7131</span><span id="line-7131"> .add(CellBuilderFactory.create(CellBuilderType.SHALLOW_COPY).setRow(b).setFamily(fam1)</span>
<span class="source-line-no">7132</span><span id="line-7132"> .setTimestamp(HConstants.LATEST_TIMESTAMP).setType(Cell.Type.Put).build()) };</span>
<span class="source-line-no">7133</span><span id="line-7133"></span>
<span class="source-line-no">7134</span><span id="line-7134"> OperationStatus[] status = region.batchMutate(mutations);</span>
<span class="source-line-no">7135</span><span id="line-7135"> assertEquals(OperationStatusCode.SUCCESS, status[0].getOperationStatusCode());</span>
<span class="source-line-no">7136</span><span id="line-7136"> assertEquals(OperationStatusCode.SANITY_CHECK_FAILURE, status[1].getOperationStatusCode());</span>
<span class="source-line-no">7137</span><span id="line-7137"> assertEquals(OperationStatusCode.SUCCESS, status[2].getOperationStatusCode());</span>
<span class="source-line-no">7138</span><span id="line-7138"></span>
<span class="source-line-no">7139</span><span id="line-7139"> // test with a row lock held for a long time</span>
<span class="source-line-no">7140</span><span id="line-7140"> final CountDownLatch obtainedRowLock = new CountDownLatch(1);</span>
<span class="source-line-no">7141</span><span id="line-7141"> ExecutorService exec = Executors.newFixedThreadPool(2);</span>
<span class="source-line-no">7142</span><span id="line-7142"> Future&lt;Void&gt; f1 = exec.submit(new Callable&lt;Void&gt;() {</span>
<span class="source-line-no">7143</span><span id="line-7143"> @Override</span>
<span class="source-line-no">7144</span><span id="line-7144"> public Void call() throws Exception {</span>
<span class="source-line-no">7145</span><span id="line-7145"> LOG.info("Acquiring row lock");</span>
<span class="source-line-no">7146</span><span id="line-7146"> RowLock rl = region.getRowLock(b);</span>
<span class="source-line-no">7147</span><span id="line-7147"> obtainedRowLock.countDown();</span>
<span class="source-line-no">7148</span><span id="line-7148"> LOG.info("Waiting for 5 seconds before releasing lock");</span>
<span class="source-line-no">7149</span><span id="line-7149"> Threads.sleep(5000);</span>
<span class="source-line-no">7150</span><span id="line-7150"> LOG.info("Releasing row lock");</span>
<span class="source-line-no">7151</span><span id="line-7151"> rl.release();</span>
<span class="source-line-no">7152</span><span id="line-7152"> return null;</span>
<span class="source-line-no">7153</span><span id="line-7153"> }</span>
<span class="source-line-no">7154</span><span id="line-7154"> });</span>
<span class="source-line-no">7155</span><span id="line-7155"> obtainedRowLock.await(30, TimeUnit.SECONDS);</span>
<span class="source-line-no">7156</span><span id="line-7156"></span>
<span class="source-line-no">7157</span><span id="line-7157"> Future&lt;Void&gt; f2 = exec.submit(new Callable&lt;Void&gt;() {</span>
<span class="source-line-no">7158</span><span id="line-7158"> @Override</span>
<span class="source-line-no">7159</span><span id="line-7159"> public Void call() throws Exception {</span>
<span class="source-line-no">7160</span><span id="line-7160"> Mutation[] mutations = new Mutation[] {</span>
<span class="source-line-no">7161</span><span id="line-7161"> new Put(a)</span>
<span class="source-line-no">7162</span><span id="line-7162"> .add(CellBuilderFactory.create(CellBuilderType.SHALLOW_COPY).setRow(a).setFamily(fam1)</span>
<span class="source-line-no">7163</span><span id="line-7163"> .setTimestamp(HConstants.LATEST_TIMESTAMP).setType(Cell.Type.Put).build()),</span>
<span class="source-line-no">7164</span><span id="line-7164"> new Put(b)</span>
<span class="source-line-no">7165</span><span id="line-7165"> .add(CellBuilderFactory.create(CellBuilderType.SHALLOW_COPY).setRow(b).setFamily(fam1)</span>
<span class="source-line-no">7166</span><span id="line-7166"> .setTimestamp(HConstants.LATEST_TIMESTAMP).setType(Cell.Type.Put).build()), };</span>
<span class="source-line-no">7167</span><span id="line-7167"></span>
<span class="source-line-no">7168</span><span id="line-7168"> // this will wait for the row lock, and it will eventually succeed</span>
<span class="source-line-no">7169</span><span id="line-7169"> OperationStatus[] status = region.batchMutate(mutations);</span>
<span class="source-line-no">7170</span><span id="line-7170"> assertEquals(OperationStatusCode.SUCCESS, status[0].getOperationStatusCode());</span>
<span class="source-line-no">7171</span><span id="line-7171"> assertEquals(OperationStatusCode.SUCCESS, status[1].getOperationStatusCode());</span>
<span class="source-line-no">7172</span><span id="line-7172"> return null;</span>
<span class="source-line-no">7173</span><span id="line-7173"> }</span>
<span class="source-line-no">7174</span><span id="line-7174"> });</span>
<span class="source-line-no">7175</span><span id="line-7175"></span>
<span class="source-line-no">7176</span><span id="line-7176"> f1.get();</span>
<span class="source-line-no">7177</span><span id="line-7177"> f2.get();</span>
<span class="source-line-no">7178</span><span id="line-7178"></span>
<span class="source-line-no">7179</span><span id="line-7179"> CONF.setInt("hbase.rowlock.wait.duration", prevLockTimeout);</span>
<span class="source-line-no">7180</span><span id="line-7180"> }</span>
<span class="source-line-no">7181</span><span id="line-7181"></span>
<span class="source-line-no">7182</span><span id="line-7182"> @Test</span>
<span class="source-line-no">7183</span><span id="line-7183"> public void testBatchMutateWithZeroRowLockWait() throws Exception {</span>
<span class="source-line-no">7184</span><span id="line-7184"> final byte[] a = Bytes.toBytes("a");</span>
<span class="source-line-no">7185</span><span id="line-7185"> final byte[] b = Bytes.toBytes("b");</span>
<span class="source-line-no">7186</span><span id="line-7186"> final byte[] c = Bytes.toBytes("c"); // exclusive</span>
<span class="source-line-no">7187</span><span id="line-7187"></span>
<span class="source-line-no">7188</span><span id="line-7188"> Configuration conf = new Configuration(CONF);</span>
<span class="source-line-no">7189</span><span id="line-7189"> conf.setInt("hbase.rowlock.wait.duration", 0);</span>
<span class="source-line-no">7190</span><span id="line-7190"> final RegionInfo hri =</span>
<span class="source-line-no">7191</span><span id="line-7191"> RegionInfoBuilder.newBuilder(tableName).setStartKey(a).setEndKey(c).build();</span>
<span class="source-line-no">7192</span><span id="line-7192"> final TableDescriptor htd = TableDescriptorBuilder.newBuilder(tableName)</span>
<span class="source-line-no">7193</span><span id="line-7193"> .setColumnFamily(ColumnFamilyDescriptorBuilder.of(fam1)).build();</span>
<span class="source-line-no">7194</span><span id="line-7194"> region = HRegion.createHRegion(hri, TEST_UTIL.getDataTestDir(), conf, htd,</span>
<span class="source-line-no">7195</span><span id="line-7195"> HBaseTestingUtil.createWal(conf, TEST_UTIL.getDataTestDirOnTestFS(method + ".log"), hri));</span>
<span class="source-line-no">7196</span><span id="line-7196"></span>
<span class="source-line-no">7197</span><span id="line-7197"> Mutation[] mutations = new Mutation[] {</span>
<span class="source-line-no">7198</span><span id="line-7198"> new Put(a).add(CellBuilderFactory.create(CellBuilderType.SHALLOW_COPY).setRow(a)</span>
<span class="source-line-no">7199</span><span id="line-7199"> .setFamily(fam1).setTimestamp(HConstants.LATEST_TIMESTAMP).setType(Cell.Type.Put).build()),</span>
<span class="source-line-no">7200</span><span id="line-7200"> new Put(b)</span>
<span class="source-line-no">7201</span><span id="line-7201"> .add(CellBuilderFactory.create(CellBuilderType.SHALLOW_COPY).setRow(b).setFamily(fam1)</span>
<span class="source-line-no">7202</span><span id="line-7202"> .setTimestamp(HConstants.LATEST_TIMESTAMP).setType(Cell.Type.Put).build()) };</span>
<span class="source-line-no">7203</span><span id="line-7203"></span>
<span class="source-line-no">7204</span><span id="line-7204"> OperationStatus[] status = region.batchMutate(mutations);</span>
<span class="source-line-no">7205</span><span id="line-7205"> assertEquals(OperationStatusCode.SUCCESS, status[0].getOperationStatusCode());</span>
<span class="source-line-no">7206</span><span id="line-7206"> assertEquals(OperationStatusCode.SUCCESS, status[1].getOperationStatusCode());</span>
<span class="source-line-no">7207</span><span id="line-7207"></span>
<span class="source-line-no">7208</span><span id="line-7208"> // test with a row lock held for a long time</span>
<span class="source-line-no">7209</span><span id="line-7209"> final CountDownLatch obtainedRowLock = new CountDownLatch(1);</span>
<span class="source-line-no">7210</span><span id="line-7210"> ExecutorService exec = Executors.newFixedThreadPool(2);</span>
<span class="source-line-no">7211</span><span id="line-7211"> Future&lt;Void&gt; f1 = exec.submit(new Callable&lt;Void&gt;() {</span>
<span class="source-line-no">7212</span><span id="line-7212"> @Override</span>
<span class="source-line-no">7213</span><span id="line-7213"> public Void call() throws Exception {</span>
<span class="source-line-no">7214</span><span id="line-7214"> LOG.info("Acquiring row lock");</span>
<span class="source-line-no">7215</span><span id="line-7215"> RowLock rl = region.getRowLock(b);</span>
<span class="source-line-no">7216</span><span id="line-7216"> obtainedRowLock.countDown();</span>
<span class="source-line-no">7217</span><span id="line-7217"> LOG.info("Waiting for 5 seconds before releasing lock");</span>
<span class="source-line-no">7218</span><span id="line-7218"> Threads.sleep(5000);</span>
<span class="source-line-no">7219</span><span id="line-7219"> LOG.info("Releasing row lock");</span>
<span class="source-line-no">7220</span><span id="line-7220"> rl.release();</span>
<span class="source-line-no">7221</span><span id="line-7221"> return null;</span>
<span class="source-line-no">7222</span><span id="line-7222"> }</span>
<span class="source-line-no">7223</span><span id="line-7223"> });</span>
<span class="source-line-no">7224</span><span id="line-7224"> obtainedRowLock.await(30, TimeUnit.SECONDS);</span>
<span class="source-line-no">7225</span><span id="line-7225"></span>
<span class="source-line-no">7226</span><span id="line-7226"> Future&lt;Void&gt; f2 = exec.submit(new Callable&lt;Void&gt;() {</span>
<span class="source-line-no">7227</span><span id="line-7227"> @Override</span>
<span class="source-line-no">7228</span><span id="line-7228"> public Void call() throws Exception {</span>
<span class="source-line-no">7229</span><span id="line-7229"> Mutation[] mutations = new Mutation[] {</span>
<span class="source-line-no">7230</span><span id="line-7230"> new Put(a)</span>
<span class="source-line-no">7231</span><span id="line-7231"> .add(CellBuilderFactory.create(CellBuilderType.SHALLOW_COPY).setRow(a).setFamily(fam1)</span>
<span class="source-line-no">7232</span><span id="line-7232"> .setTimestamp(HConstants.LATEST_TIMESTAMP).setType(Cell.Type.Put).build()),</span>
<span class="source-line-no">7233</span><span id="line-7233"> new Put(b)</span>
<span class="source-line-no">7234</span><span id="line-7234"> .add(CellBuilderFactory.create(CellBuilderType.SHALLOW_COPY).setRow(b).setFamily(fam1)</span>
<span class="source-line-no">7235</span><span id="line-7235"> .setTimestamp(HConstants.LATEST_TIMESTAMP).setType(Cell.Type.Put).build()), };</span>
<span class="source-line-no">7236</span><span id="line-7236"> // when handling row b we are going to spin on the failure to get the row lock</span>
<span class="source-line-no">7237</span><span id="line-7237"> // until the lock above is released, but we will still succeed so long as that</span>
<span class="source-line-no">7238</span><span id="line-7238"> // takes less time then the test time out.</span>
<span class="source-line-no">7239</span><span id="line-7239"> OperationStatus[] status = region.batchMutate(mutations);</span>
<span class="source-line-no">7240</span><span id="line-7240"> assertEquals(OperationStatusCode.SUCCESS, status[0].getOperationStatusCode());</span>
<span class="source-line-no">7241</span><span id="line-7241"> assertEquals(OperationStatusCode.SUCCESS, status[1].getOperationStatusCode());</span>
<span class="source-line-no">7242</span><span id="line-7242"> return null;</span>
<span class="source-line-no">7243</span><span id="line-7243"> }</span>
<span class="source-line-no">7244</span><span id="line-7244"> });</span>
<span class="source-line-no">7245</span><span id="line-7245"></span>
<span class="source-line-no">7246</span><span id="line-7246"> f1.get();</span>
<span class="source-line-no">7247</span><span id="line-7247"> f2.get();</span>
<span class="source-line-no">7248</span><span id="line-7248"> }</span>
<span class="source-line-no">7249</span><span id="line-7249"></span>
<span class="source-line-no">7250</span><span id="line-7250"> @Test</span>
<span class="source-line-no">7251</span><span id="line-7251"> public void testCheckAndRowMutateTimestampsAreMonotonic() throws IOException {</span>
<span class="source-line-no">7252</span><span id="line-7252"> region = initHRegion(tableName, method, CONF, fam1);</span>
<span class="source-line-no">7253</span><span id="line-7253"> ManualEnvironmentEdge edge = new ManualEnvironmentEdge();</span>
<span class="source-line-no">7254</span><span id="line-7254"> EnvironmentEdgeManager.injectEdge(edge);</span>
<span class="source-line-no">7255</span><span id="line-7255"></span>
<span class="source-line-no">7256</span><span id="line-7256"> edge.setValue(10);</span>
<span class="source-line-no">7257</span><span id="line-7257"> Put p = new Put(row);</span>
<span class="source-line-no">7258</span><span id="line-7258"> p.setDurability(Durability.SKIP_WAL);</span>
<span class="source-line-no">7259</span><span id="line-7259"> p.addColumn(fam1, qual1, qual1);</span>
<span class="source-line-no">7260</span><span id="line-7260"> region.put(p);</span>
<span class="source-line-no">7261</span><span id="line-7261"></span>
<span class="source-line-no">7262</span><span id="line-7262"> Result result = region.get(new Get(row));</span>
<span class="source-line-no">7263</span><span id="line-7263"> Cell c = result.getColumnLatestCell(fam1, qual1);</span>
<span class="source-line-no">7264</span><span id="line-7264"> assertNotNull(c);</span>
<span class="source-line-no">7265</span><span id="line-7265"> assertEquals(10L, c.getTimestamp());</span>
<span class="source-line-no">7266</span><span id="line-7266"></span>
<span class="source-line-no">7267</span><span id="line-7267"> edge.setValue(1); // clock goes back</span>
<span class="source-line-no">7268</span><span id="line-7268"> p = new Put(row);</span>
<span class="source-line-no">7269</span><span id="line-7269"> p.setDurability(Durability.SKIP_WAL);</span>
<span class="source-line-no">7270</span><span id="line-7270"> p.addColumn(fam1, qual1, qual2);</span>
<span class="source-line-no">7271</span><span id="line-7271"> RowMutations rm = new RowMutations(row);</span>
<span class="source-line-no">7272</span><span id="line-7272"> rm.add(p);</span>
<span class="source-line-no">7273</span><span id="line-7273"> assertTrue(region.checkAndRowMutate(row, fam1, qual1, CompareOperator.EQUAL,</span>
<span class="source-line-no">7274</span><span id="line-7274"> new BinaryComparator(qual1), rm));</span>
<span class="source-line-no">7275</span><span id="line-7275"> result = region.get(new Get(row));</span>
<span class="source-line-no">7276</span><span id="line-7276"> c = result.getColumnLatestCell(fam1, qual1);</span>
<span class="source-line-no">7277</span><span id="line-7277"> assertEquals(10L, c.getTimestamp());</span>
<span class="source-line-no">7278</span><span id="line-7278"> LOG.info(</span>
<span class="source-line-no">7279</span><span id="line-7279"> "c value " + Bytes.toStringBinary(c.getValueArray(), c.getValueOffset(), c.getValueLength()));</span>
<span class="source-line-no">7280</span><span id="line-7280"></span>
<span class="source-line-no">7281</span><span id="line-7281"> assertTrue(Bytes.equals(c.getValueArray(), c.getValueOffset(), c.getValueLength(), qual2, 0,</span>
<span class="source-line-no">7282</span><span id="line-7282"> qual2.length));</span>
<span class="source-line-no">7283</span><span id="line-7283"> }</span>
<span class="source-line-no">7284</span><span id="line-7284"></span>
<span class="source-line-no">7285</span><span id="line-7285"> private HRegion initHRegion(TableName tableName, String callingMethod, byte[]... families)</span>
<span class="source-line-no">7286</span><span id="line-7286"> throws IOException {</span>
<span class="source-line-no">7287</span><span id="line-7287"> return initHRegion(tableName, callingMethod, HBaseConfiguration.create(), families);</span>
<span class="source-line-no">7288</span><span id="line-7288"> }</span>
<span class="source-line-no">7289</span><span id="line-7289"></span>
<span class="source-line-no">7290</span><span id="line-7290"> /**</span>
<span class="source-line-no">7291</span><span id="line-7291"> * HBASE-16429 Make sure no stuck if roll writer when ring buffer is filled with appends</span>
<span class="source-line-no">7292</span><span id="line-7292"> * @throws IOException if IO error occurred during test</span>
<span class="source-line-no">7293</span><span id="line-7293"> */</span>
<span class="source-line-no">7294</span><span id="line-7294"> @Test</span>
<span class="source-line-no">7295</span><span id="line-7295"> public void testWritesWhileRollWriter() throws IOException {</span>
<span class="source-line-no">7296</span><span id="line-7296"> int testCount = 10;</span>
<span class="source-line-no">7297</span><span id="line-7297"> int numRows = 1024;</span>
<span class="source-line-no">7298</span><span id="line-7298"> int numFamilies = 2;</span>
<span class="source-line-no">7299</span><span id="line-7299"> int numQualifiers = 2;</span>
<span class="source-line-no">7300</span><span id="line-7300"> final byte[][] families = new byte[numFamilies][];</span>
<span class="source-line-no">7301</span><span id="line-7301"> for (int i = 0; i &lt; numFamilies; i++) {</span>
<span class="source-line-no">7302</span><span id="line-7302"> families[i] = Bytes.toBytes("family" + i);</span>
<span class="source-line-no">7303</span><span id="line-7303"> }</span>
<span class="source-line-no">7304</span><span id="line-7304"> final byte[][] qualifiers = new byte[numQualifiers][];</span>
<span class="source-line-no">7305</span><span id="line-7305"> for (int i = 0; i &lt; numQualifiers; i++) {</span>
<span class="source-line-no">7306</span><span id="line-7306"> qualifiers[i] = Bytes.toBytes("qual" + i);</span>
<span class="source-line-no">7307</span><span id="line-7307"> }</span>
<span class="source-line-no">7308</span><span id="line-7308"></span>
<span class="source-line-no">7309</span><span id="line-7309"> CONF.setInt("hbase.regionserver.wal.disruptor.event.count", 2);</span>
<span class="source-line-no">7310</span><span id="line-7310"> this.region = initHRegion(tableName, method, CONF, families);</span>
<span class="source-line-no">7311</span><span id="line-7311"> try {</span>
<span class="source-line-no">7312</span><span id="line-7312"> List&lt;Thread&gt; threads = new ArrayList&lt;&gt;();</span>
<span class="source-line-no">7313</span><span id="line-7313"> for (int i = 0; i &lt; numRows; i++) {</span>
<span class="source-line-no">7314</span><span id="line-7314"> final int count = i;</span>
<span class="source-line-no">7315</span><span id="line-7315"> Thread t = new Thread(new Runnable() {</span>
<span class="source-line-no">7316</span><span id="line-7316"></span>
<span class="source-line-no">7317</span><span id="line-7317"> @Override</span>
<span class="source-line-no">7318</span><span id="line-7318"> public void run() {</span>
<span class="source-line-no">7319</span><span id="line-7319"> byte[] row = Bytes.toBytes("row" + count);</span>
<span class="source-line-no">7320</span><span id="line-7320"> Put put = new Put(row);</span>
<span class="source-line-no">7321</span><span id="line-7321"> put.setDurability(Durability.SYNC_WAL);</span>
<span class="source-line-no">7322</span><span id="line-7322"> byte[] value = Bytes.toBytes(String.valueOf(count));</span>
<span class="source-line-no">7323</span><span id="line-7323"> for (byte[] family : families) {</span>
<span class="source-line-no">7324</span><span id="line-7324"> for (byte[] qualifier : qualifiers) {</span>
<span class="source-line-no">7325</span><span id="line-7325"> put.addColumn(family, qualifier, count, value);</span>
<span class="source-line-no">7326</span><span id="line-7326"> }</span>
<span class="source-line-no">7327</span><span id="line-7327"> }</span>
<span class="source-line-no">7328</span><span id="line-7328"> try {</span>
<span class="source-line-no">7329</span><span id="line-7329"> region.put(put);</span>
<span class="source-line-no">7330</span><span id="line-7330"> } catch (IOException e) {</span>
<span class="source-line-no">7331</span><span id="line-7331"> throw new RuntimeException(e);</span>
<span class="source-line-no">7332</span><span id="line-7332"> }</span>
<span class="source-line-no">7333</span><span id="line-7333"> }</span>
<span class="source-line-no">7334</span><span id="line-7334"> });</span>
<span class="source-line-no">7335</span><span id="line-7335"> threads.add(t);</span>
<span class="source-line-no">7336</span><span id="line-7336"> }</span>
<span class="source-line-no">7337</span><span id="line-7337"> for (Thread t : threads) {</span>
<span class="source-line-no">7338</span><span id="line-7338"> t.start();</span>
<span class="source-line-no">7339</span><span id="line-7339"> }</span>
<span class="source-line-no">7340</span><span id="line-7340"></span>
<span class="source-line-no">7341</span><span id="line-7341"> for (int i = 0; i &lt; testCount; i++) {</span>
<span class="source-line-no">7342</span><span id="line-7342"> region.getWAL().rollWriter();</span>
<span class="source-line-no">7343</span><span id="line-7343"> Thread.yield();</span>
<span class="source-line-no">7344</span><span id="line-7344"> }</span>
<span class="source-line-no">7345</span><span id="line-7345"> } finally {</span>
<span class="source-line-no">7346</span><span id="line-7346"> try {</span>
<span class="source-line-no">7347</span><span id="line-7347"> HBaseTestingUtil.closeRegionAndWAL(this.region);</span>
<span class="source-line-no">7348</span><span id="line-7348"> CONF.setInt("hbase.regionserver.wal.disruptor.event.count", 16 * 1024);</span>
<span class="source-line-no">7349</span><span id="line-7349"> } catch (DroppedSnapshotException dse) {</span>
<span class="source-line-no">7350</span><span id="line-7350"> // We could get this on way out because we interrupt the background flusher and it could</span>
<span class="source-line-no">7351</span><span id="line-7351"> // fail anywhere causing a DSE over in the background flusher... only it is not properly</span>
<span class="source-line-no">7352</span><span id="line-7352"> // dealt with so could still be memory hanging out when we get to here -- memory we can't</span>
<span class="source-line-no">7353</span><span id="line-7353"> // flush because the accounting is 'off' since original DSE.</span>
<span class="source-line-no">7354</span><span id="line-7354"> }</span>
<span class="source-line-no">7355</span><span id="line-7355"> this.region = null;</span>
<span class="source-line-no">7356</span><span id="line-7356"> }</span>
<span class="source-line-no">7357</span><span id="line-7357"> }</span>
<span class="source-line-no">7358</span><span id="line-7358"></span>
<span class="source-line-no">7359</span><span id="line-7359"> @Test</span>
<span class="source-line-no">7360</span><span id="line-7360"> public void testMutateRow() throws Exception {</span>
<span class="source-line-no">7361</span><span id="line-7361"> final byte[] row = Bytes.toBytes("row");</span>
<span class="source-line-no">7362</span><span id="line-7362"> final byte[] q1 = Bytes.toBytes("q1");</span>
<span class="source-line-no">7363</span><span id="line-7363"> final byte[] q2 = Bytes.toBytes("q2");</span>
<span class="source-line-no">7364</span><span id="line-7364"> final byte[] q3 = Bytes.toBytes("q3");</span>
<span class="source-line-no">7365</span><span id="line-7365"> final byte[] q4 = Bytes.toBytes("q4");</span>
<span class="source-line-no">7366</span><span id="line-7366"> final String v1 = "v1";</span>
<span class="source-line-no">7367</span><span id="line-7367"></span>
<span class="source-line-no">7368</span><span id="line-7368"> region = initHRegion(tableName, method, CONF, fam1);</span>
<span class="source-line-no">7369</span><span id="line-7369"></span>
<span class="source-line-no">7370</span><span id="line-7370"> // Initial values</span>
<span class="source-line-no">7371</span><span id="line-7371"> region</span>
<span class="source-line-no">7372</span><span id="line-7372"> .batchMutate(new Mutation[] { new Put(row).addColumn(fam1, q2, Bytes.toBytes("toBeDeleted")),</span>
<span class="source-line-no">7373</span><span id="line-7373"> new Put(row).addColumn(fam1, q3, Bytes.toBytes(5L)),</span>
<span class="source-line-no">7374</span><span id="line-7374"> new Put(row).addColumn(fam1, q4, Bytes.toBytes("a")), });</span>
<span class="source-line-no">7375</span><span id="line-7375"></span>
<span class="source-line-no">7376</span><span id="line-7376"> // Do mutateRow</span>
<span class="source-line-no">7377</span><span id="line-7377"> Result result = region.mutateRow(</span>
<span class="source-line-no">7378</span><span id="line-7378"> new RowMutations(row).add(Arrays.asList(new Put(row).addColumn(fam1, q1, Bytes.toBytes(v1)),</span>
<span class="source-line-no">7379</span><span id="line-7379"> new Delete(row).addColumns(fam1, q2), new Increment(row).addColumn(fam1, q3, 1),</span>
<span class="source-line-no">7380</span><span id="line-7380"> new Append(row).addColumn(fam1, q4, Bytes.toBytes("b")))));</span>
<span class="source-line-no">7381</span><span id="line-7381"></span>
<span class="source-line-no">7382</span><span id="line-7382"> assertNotNull(result);</span>
<span class="source-line-no">7383</span><span id="line-7383"> assertEquals(6L, Bytes.toLong(result.getValue(fam1, q3)));</span>
<span class="source-line-no">7384</span><span id="line-7384"> assertEquals("ab", Bytes.toString(result.getValue(fam1, q4)));</span>
<span class="source-line-no">7385</span><span id="line-7385"></span>
<span class="source-line-no">7386</span><span id="line-7386"> // Verify the value</span>
<span class="source-line-no">7387</span><span id="line-7387"> result = region.get(new Get(row));</span>
<span class="source-line-no">7388</span><span id="line-7388"> assertEquals(v1, Bytes.toString(result.getValue(fam1, q1)));</span>
<span class="source-line-no">7389</span><span id="line-7389"> assertNull(result.getValue(fam1, q2));</span>
<span class="source-line-no">7390</span><span id="line-7390"> assertEquals(6L, Bytes.toLong(result.getValue(fam1, q3)));</span>
<span class="source-line-no">7391</span><span id="line-7391"> assertEquals("ab", Bytes.toString(result.getValue(fam1, q4)));</span>
<span class="source-line-no">7392</span><span id="line-7392"> }</span>
<span class="source-line-no">7393</span><span id="line-7393"></span>
<span class="source-line-no">7394</span><span id="line-7394"> @Test</span>
<span class="source-line-no">7395</span><span id="line-7395"> public void testMutateRowInParallel() throws Exception {</span>
<span class="source-line-no">7396</span><span id="line-7396"> final int numReaderThreads = 100;</span>
<span class="source-line-no">7397</span><span id="line-7397"> final CountDownLatch latch = new CountDownLatch(numReaderThreads);</span>
<span class="source-line-no">7398</span><span id="line-7398"></span>
<span class="source-line-no">7399</span><span id="line-7399"> final byte[] row = Bytes.toBytes("row");</span>
<span class="source-line-no">7400</span><span id="line-7400"> final byte[] q1 = Bytes.toBytes("q1");</span>
<span class="source-line-no">7401</span><span id="line-7401"> final byte[] q2 = Bytes.toBytes("q2");</span>
<span class="source-line-no">7402</span><span id="line-7402"> final byte[] q3 = Bytes.toBytes("q3");</span>
<span class="source-line-no">7403</span><span id="line-7403"> final byte[] q4 = Bytes.toBytes("q4");</span>
<span class="source-line-no">7404</span><span id="line-7404"> final String v1 = "v1";</span>
<span class="source-line-no">7405</span><span id="line-7405"> final String v2 = "v2";</span>
<span class="source-line-no">7406</span><span id="line-7406"></span>
<span class="source-line-no">7407</span><span id="line-7407"> // We need to ensure the timestamp of the delete operation is more than the previous one</span>
<span class="source-line-no">7408</span><span id="line-7408"> final AtomicLong deleteTimestamp = new AtomicLong();</span>
<span class="source-line-no">7409</span><span id="line-7409"></span>
<span class="source-line-no">7410</span><span id="line-7410"> region = initHRegion(tableName, method, CONF, fam1);</span>
<span class="source-line-no">7411</span><span id="line-7411"></span>
<span class="source-line-no">7412</span><span id="line-7412"> // Initial values</span>
<span class="source-line-no">7413</span><span id="line-7413"> region.batchMutate(new Mutation[] { new Put(row).addColumn(fam1, q1, Bytes.toBytes(v1))</span>
<span class="source-line-no">7414</span><span id="line-7414"> .addColumn(fam1, q2, deleteTimestamp.getAndIncrement(), Bytes.toBytes(v2))</span>
<span class="source-line-no">7415</span><span id="line-7415"> .addColumn(fam1, q3, Bytes.toBytes(1L)).addColumn(fam1, q4, Bytes.toBytes("a")) });</span>
<span class="source-line-no">7416</span><span id="line-7416"></span>
<span class="source-line-no">7417</span><span id="line-7417"> final AtomicReference&lt;AssertionError&gt; assertionError = new AtomicReference&lt;&gt;();</span>
<span class="source-line-no">7418</span><span id="line-7418"></span>
<span class="source-line-no">7419</span><span id="line-7419"> // Writer thread</span>
<span class="source-line-no">7420</span><span id="line-7420"> Thread writerThread = new Thread(() -&gt; {</span>
<span class="source-line-no">7421</span><span id="line-7421"> try {</span>
<span class="source-line-no">7422</span><span id="line-7422"> while (true) {</span>
<span class="source-line-no">7423</span><span id="line-7423"> // If all the reader threads finish, then stop the writer thread</span>
<span class="source-line-no">7424</span><span id="line-7424"> if (latch.await(0, TimeUnit.MILLISECONDS)) {</span>
<span class="source-line-no">7425</span><span id="line-7425"> return;</span>
<span class="source-line-no">7426</span><span id="line-7426"> }</span>
<span class="source-line-no">7427</span><span id="line-7427"></span>
<span class="source-line-no">7428</span><span id="line-7428"> // Execute the mutations. This should be done atomically</span>
<span class="source-line-no">7429</span><span id="line-7429"> region.mutateRow(new RowMutations(row)</span>
<span class="source-line-no">7430</span><span id="line-7430"> .add(Arrays.asList(new Put(row).addColumn(fam1, q1, Bytes.toBytes(v2)),</span>
<span class="source-line-no">7431</span><span id="line-7431"> new Delete(row).addColumns(fam1, q2, deleteTimestamp.getAndIncrement()),</span>
<span class="source-line-no">7432</span><span id="line-7432"> new Increment(row).addColumn(fam1, q3, 1L),</span>
<span class="source-line-no">7433</span><span id="line-7433"> new Append(row).addColumn(fam1, q4, Bytes.toBytes("b")))));</span>
<span class="source-line-no">7434</span><span id="line-7434"></span>
<span class="source-line-no">7435</span><span id="line-7435"> // We need to ensure the timestamps of the Increment/Append operations are more than the</span>
<span class="source-line-no">7436</span><span id="line-7436"> // previous ones</span>
<span class="source-line-no">7437</span><span id="line-7437"> Result result = region.get(new Get(row).addColumn(fam1, q3).addColumn(fam1, q4));</span>
<span class="source-line-no">7438</span><span id="line-7438"> long tsIncrement = result.getColumnLatestCell(fam1, q3).getTimestamp();</span>
<span class="source-line-no">7439</span><span id="line-7439"> long tsAppend = result.getColumnLatestCell(fam1, q4).getTimestamp();</span>
<span class="source-line-no">7440</span><span id="line-7440"></span>
<span class="source-line-no">7441</span><span id="line-7441"> // Put the initial values</span>
<span class="source-line-no">7442</span><span id="line-7442"> region.batchMutate(new Mutation[] { new Put(row).addColumn(fam1, q1, Bytes.toBytes(v1))</span>
<span class="source-line-no">7443</span><span id="line-7443"> .addColumn(fam1, q2, deleteTimestamp.getAndIncrement(), Bytes.toBytes(v2))</span>
<span class="source-line-no">7444</span><span id="line-7444"> .addColumn(fam1, q3, tsIncrement + 1, Bytes.toBytes(1L))</span>
<span class="source-line-no">7445</span><span id="line-7445"> .addColumn(fam1, q4, tsAppend + 1, Bytes.toBytes("a")) });</span>
<span class="source-line-no">7446</span><span id="line-7446"> }</span>
<span class="source-line-no">7447</span><span id="line-7447"> } catch (Exception e) {</span>
<span class="source-line-no">7448</span><span id="line-7448"> assertionError.set(new AssertionError(e));</span>
<span class="source-line-no">7449</span><span id="line-7449"> }</span>
<span class="source-line-no">7450</span><span id="line-7450"> });</span>
<span class="source-line-no">7451</span><span id="line-7451"> writerThread.start();</span>
<span class="source-line-no">7452</span><span id="line-7452"></span>
<span class="source-line-no">7453</span><span id="line-7453"> // Reader threads</span>
<span class="source-line-no">7454</span><span id="line-7454"> for (int i = 0; i &lt; numReaderThreads; i++) {</span>
<span class="source-line-no">7455</span><span id="line-7455"> new Thread(() -&gt; {</span>
<span class="source-line-no">7456</span><span id="line-7456"> try {</span>
<span class="source-line-no">7457</span><span id="line-7457"> for (int j = 0; j &lt; 10000; j++) {</span>
<span class="source-line-no">7458</span><span id="line-7458"> // Verify the values</span>
<span class="source-line-no">7459</span><span id="line-7459"> Result result = region.get(new Get(row));</span>
<span class="source-line-no">7460</span><span id="line-7460"></span>
<span class="source-line-no">7461</span><span id="line-7461"> // The values should be equals to either the initial values or the values after</span>
<span class="source-line-no">7462</span><span id="line-7462"> // executing the mutations</span>
<span class="source-line-no">7463</span><span id="line-7463"> String q1Value = Bytes.toString(result.getValue(fam1, q1));</span>
<span class="source-line-no">7464</span><span id="line-7464"> if (v1.equals(q1Value)) {</span>
<span class="source-line-no">7465</span><span id="line-7465"> assertEquals(v2, Bytes.toString(result.getValue(fam1, q2)));</span>
<span class="source-line-no">7466</span><span id="line-7466"> assertEquals(1L, Bytes.toLong(result.getValue(fam1, q3)));</span>
<span class="source-line-no">7467</span><span id="line-7467"> assertEquals("a", Bytes.toString(result.getValue(fam1, q4)));</span>
<span class="source-line-no">7468</span><span id="line-7468"> } else if (v2.equals(q1Value)) {</span>
<span class="source-line-no">7469</span><span id="line-7469"> assertNull(Bytes.toString(result.getValue(fam1, q2)));</span>
<span class="source-line-no">7470</span><span id="line-7470"> assertEquals(2L, Bytes.toLong(result.getValue(fam1, q3)));</span>
<span class="source-line-no">7471</span><span id="line-7471"> assertEquals("ab", Bytes.toString(result.getValue(fam1, q4)));</span>
<span class="source-line-no">7472</span><span id="line-7472"> } else {</span>
<span class="source-line-no">7473</span><span id="line-7473"> fail("the qualifier " + Bytes.toString(q1) + " should be " + v1 + " or " + v2</span>
<span class="source-line-no">7474</span><span id="line-7474"> + ", but " + q1Value);</span>
<span class="source-line-no">7475</span><span id="line-7475"> }</span>
<span class="source-line-no">7476</span><span id="line-7476"> }</span>
<span class="source-line-no">7477</span><span id="line-7477"> } catch (Exception e) {</span>
<span class="source-line-no">7478</span><span id="line-7478"> assertionError.set(new AssertionError(e));</span>
<span class="source-line-no">7479</span><span id="line-7479"> } catch (AssertionError e) {</span>
<span class="source-line-no">7480</span><span id="line-7480"> assertionError.set(e);</span>
<span class="source-line-no">7481</span><span id="line-7481"> }</span>
<span class="source-line-no">7482</span><span id="line-7482"></span>
<span class="source-line-no">7483</span><span id="line-7483"> latch.countDown();</span>
<span class="source-line-no">7484</span><span id="line-7484"> }).start();</span>
<span class="source-line-no">7485</span><span id="line-7485"> }</span>
<span class="source-line-no">7486</span><span id="line-7486"></span>
<span class="source-line-no">7487</span><span id="line-7487"> writerThread.join();</span>
<span class="source-line-no">7488</span><span id="line-7488"></span>
<span class="source-line-no">7489</span><span id="line-7489"> if (assertionError.get() != null) {</span>
<span class="source-line-no">7490</span><span id="line-7490"> throw assertionError.get();</span>
<span class="source-line-no">7491</span><span id="line-7491"> }</span>
<span class="source-line-no">7492</span><span id="line-7492"> }</span>
<span class="source-line-no">7493</span><span id="line-7493"></span>
<span class="source-line-no">7494</span><span id="line-7494"> @Test</span>
<span class="source-line-no">7495</span><span id="line-7495"> public void testMutateRow_WriteRequestCount() throws Exception {</span>
<span class="source-line-no">7496</span><span id="line-7496"> byte[] row1 = Bytes.toBytes("row1");</span>
<span class="source-line-no">7497</span><span id="line-7497"> byte[] fam1 = Bytes.toBytes("fam1");</span>
<span class="source-line-no">7498</span><span id="line-7498"> byte[] qf1 = Bytes.toBytes("qualifier");</span>
<span class="source-line-no">7499</span><span id="line-7499"> byte[] val1 = Bytes.toBytes("value1");</span>
<span class="source-line-no">7500</span><span id="line-7500"></span>
<span class="source-line-no">7501</span><span id="line-7501"> RowMutations rm = new RowMutations(row1);</span>
<span class="source-line-no">7502</span><span id="line-7502"> Put put = new Put(row1);</span>
<span class="source-line-no">7503</span><span id="line-7503"> put.addColumn(fam1, qf1, val1);</span>
<span class="source-line-no">7504</span><span id="line-7504"> rm.add(put);</span>
<span class="source-line-no">7505</span><span id="line-7505"></span>
<span class="source-line-no">7506</span><span id="line-7506"> this.region = initHRegion(tableName, method, CONF, fam1);</span>
<span class="source-line-no">7507</span><span id="line-7507"> long wrcBeforeMutate = this.region.writeRequestsCount.longValue();</span>
<span class="source-line-no">7508</span><span id="line-7508"> this.region.mutateRow(rm);</span>
<span class="source-line-no">7509</span><span id="line-7509"> long wrcAfterMutate = this.region.writeRequestsCount.longValue();</span>
<span class="source-line-no">7510</span><span id="line-7510"> Assert.assertEquals(wrcBeforeMutate + rm.getMutations().size(), wrcAfterMutate);</span>
<span class="source-line-no">7511</span><span id="line-7511"> }</span>
<span class="source-line-no">7512</span><span id="line-7512"></span>
<span class="source-line-no">7513</span><span id="line-7513"> @Test</span>
<span class="source-line-no">7514</span><span id="line-7514"> public void testBulkLoadReplicationEnabled() throws IOException {</span>
<span class="source-line-no">7515</span><span id="line-7515"> TEST_UTIL.getConfiguration().setBoolean(HConstants.REPLICATION_BULKLOAD_ENABLE_KEY, true);</span>
<span class="source-line-no">7516</span><span id="line-7516"> final ServerName serverName = ServerName.valueOf(name.getMethodName(), 100, 42);</span>
<span class="source-line-no">7517</span><span id="line-7517"> final RegionServerServices rss = spy(TEST_UTIL.createMockRegionServerService(serverName));</span>
<span class="source-line-no">7518</span><span id="line-7518"></span>
<span class="source-line-no">7519</span><span id="line-7519"> TableDescriptor tableDescriptor =</span>
<span class="source-line-no">7520</span><span id="line-7520"> TableDescriptorBuilder.newBuilder(TableName.valueOf(name.getMethodName()))</span>
<span class="source-line-no">7521</span><span id="line-7521"> .setColumnFamily(ColumnFamilyDescriptorBuilder.of(fam1)).build();</span>
<span class="source-line-no">7522</span><span id="line-7522"> RegionInfo hri = RegionInfoBuilder.newBuilder(tableDescriptor.getTableName()).build();</span>
<span class="source-line-no">7523</span><span id="line-7523"> region = HRegion.openHRegion(hri, tableDescriptor, rss.getWAL(hri),</span>
<span class="source-line-no">7524</span><span id="line-7524"> TEST_UTIL.getConfiguration(), rss, null);</span>
<span class="source-line-no">7525</span><span id="line-7525"></span>
<span class="source-line-no">7526</span><span id="line-7526"> assertTrue(region.conf.getBoolean(HConstants.REPLICATION_BULKLOAD_ENABLE_KEY, false));</span>
<span class="source-line-no">7527</span><span id="line-7527"> String plugins = region.conf.get(CoprocessorHost.REGION_COPROCESSOR_CONF_KEY, "");</span>
<span class="source-line-no">7528</span><span id="line-7528"> String replicationCoprocessorClass = ReplicationObserver.class.getCanonicalName();</span>
<span class="source-line-no">7529</span><span id="line-7529"> assertTrue(plugins.contains(replicationCoprocessorClass));</span>
<span class="source-line-no">7530</span><span id="line-7530"> assertTrue(region.getCoprocessorHost().getCoprocessors()</span>
<span class="source-line-no">7531</span><span id="line-7531"> .contains(ReplicationObserver.class.getSimpleName()));</span>
<span class="source-line-no">7532</span><span id="line-7532"> }</span>
<span class="source-line-no">7533</span><span id="line-7533"></span>
<span class="source-line-no">7534</span><span id="line-7534"> /**</span>
<span class="source-line-no">7535</span><span id="line-7535"> * The same as HRegion class, the only difference is that instantiateHStore will create a</span>
<span class="source-line-no">7536</span><span id="line-7536"> * different HStore - HStoreForTesting. [HBASE-8518]</span>
<span class="source-line-no">7537</span><span id="line-7537"> */</span>
<span class="source-line-no">7538</span><span id="line-7538"> public static class HRegionForTesting extends HRegion {</span>
<span class="source-line-no">7539</span><span id="line-7539"></span>
<span class="source-line-no">7540</span><span id="line-7540"> public HRegionForTesting(final Path tableDir, final WAL wal, final FileSystem fs,</span>
<span class="source-line-no">7541</span><span id="line-7541"> final Configuration confParam, final RegionInfo regionInfo, final TableDescriptor htd,</span>
<span class="source-line-no">7542</span><span id="line-7542"> final RegionServerServices rsServices) {</span>
<span class="source-line-no">7543</span><span id="line-7543"> this(new HRegionFileSystem(confParam, fs, tableDir, regionInfo), wal, confParam, htd,</span>
<span class="source-line-no">7544</span><span id="line-7544"> rsServices);</span>
<span class="source-line-no">7545</span><span id="line-7545"> }</span>
<span class="source-line-no">7546</span><span id="line-7546"></span>
<span class="source-line-no">7547</span><span id="line-7547"> public HRegionForTesting(HRegionFileSystem fs, WAL wal, Configuration confParam,</span>
<span class="source-line-no">7548</span><span id="line-7548"> TableDescriptor htd, RegionServerServices rsServices) {</span>
<span class="source-line-no">7549</span><span id="line-7549"> super(fs, wal, confParam, htd, rsServices);</span>
<span class="source-line-no">7550</span><span id="line-7550"> }</span>
<span class="source-line-no">7551</span><span id="line-7551"></span>
<span class="source-line-no">7552</span><span id="line-7552"> /**</span>
<span class="source-line-no">7553</span><span id="line-7553"> * Create HStore instance.</span>
<span class="source-line-no">7554</span><span id="line-7554"> * @return If Mob is enabled, return HMobStore, otherwise return HStoreForTesting.</span>
<span class="source-line-no">7555</span><span id="line-7555"> */</span>
<span class="source-line-no">7556</span><span id="line-7556"> @Override</span>
<span class="source-line-no">7557</span><span id="line-7557"> protected HStore instantiateHStore(final ColumnFamilyDescriptor family, boolean warmup)</span>
<span class="source-line-no">7558</span><span id="line-7558"> throws IOException {</span>
<span class="source-line-no">7559</span><span id="line-7559"> if (family.isMobEnabled()) {</span>
<span class="source-line-no">7560</span><span id="line-7560"> if (HFile.getFormatVersion(this.conf) &lt; HFile.MIN_FORMAT_VERSION_WITH_TAGS) {</span>
<span class="source-line-no">7561</span><span id="line-7561"> throw new IOException("A minimum HFile version of " + HFile.MIN_FORMAT_VERSION_WITH_TAGS</span>
<span class="source-line-no">7562</span><span id="line-7562"> + " is required for MOB feature. Consider setting " + HFile.FORMAT_VERSION_KEY</span>
<span class="source-line-no">7563</span><span id="line-7563"> + " accordingly.");</span>
<span class="source-line-no">7564</span><span id="line-7564"> }</span>
<span class="source-line-no">7565</span><span id="line-7565"> return new HMobStore(this, family, this.conf, warmup);</span>
<span class="source-line-no">7566</span><span id="line-7566"> }</span>
<span class="source-line-no">7567</span><span id="line-7567"> return new HStoreForTesting(this, family, this.conf, warmup);</span>
<span class="source-line-no">7568</span><span id="line-7568"> }</span>
<span class="source-line-no">7569</span><span id="line-7569"> }</span>
<span class="source-line-no">7570</span><span id="line-7570"></span>
<span class="source-line-no">7571</span><span id="line-7571"> /**</span>
<span class="source-line-no">7572</span><span id="line-7572"> * HStoreForTesting is merely the same as HStore, the difference is in the doCompaction method of</span>
<span class="source-line-no">7573</span><span id="line-7573"> * HStoreForTesting there is a checkpoint "hbase.hstore.compaction.complete" which doesn't let</span>
<span class="source-line-no">7574</span><span id="line-7574"> * hstore compaction complete. In the former edition, this config is set in HStore class inside</span>
<span class="source-line-no">7575</span><span id="line-7575"> * compact method, though this is just for testing, otherwise it doesn't do any help. In</span>
<span class="source-line-no">7576</span><span id="line-7576"> * HBASE-8518, we try to get rid of all "hbase.hstore.compaction.complete" config (except for</span>
<span class="source-line-no">7577</span><span id="line-7577"> * testing code).</span>
<span class="source-line-no">7578</span><span id="line-7578"> */</span>
<span class="source-line-no">7579</span><span id="line-7579"> public static class HStoreForTesting extends HStore {</span>
<span class="source-line-no">7580</span><span id="line-7580"></span>
<span class="source-line-no">7581</span><span id="line-7581"> protected HStoreForTesting(final HRegion region, final ColumnFamilyDescriptor family,</span>
<span class="source-line-no">7582</span><span id="line-7582"> final Configuration confParam, boolean warmup) throws IOException {</span>
<span class="source-line-no">7583</span><span id="line-7583"> super(region, family, confParam, warmup);</span>
<span class="source-line-no">7584</span><span id="line-7584"> }</span>
<span class="source-line-no">7585</span><span id="line-7585"></span>
<span class="source-line-no">7586</span><span id="line-7586"> @Override</span>
<span class="source-line-no">7587</span><span id="line-7587"> protected List&lt;HStoreFile&gt; doCompaction(CompactionRequestImpl cr,</span>
<span class="source-line-no">7588</span><span id="line-7588"> Collection&lt;HStoreFile&gt; filesToCompact, User user, long compactionStartTime,</span>
<span class="source-line-no">7589</span><span id="line-7589"> List&lt;Path&gt; newFiles) throws IOException {</span>
<span class="source-line-no">7590</span><span id="line-7590"> // let compaction incomplete.</span>
<span class="source-line-no">7591</span><span id="line-7591"> if (!this.conf.getBoolean("hbase.hstore.compaction.complete", true)) {</span>
<span class="source-line-no">7592</span><span id="line-7592"> LOG.warn("hbase.hstore.compaction.complete is set to false");</span>
<span class="source-line-no">7593</span><span id="line-7593"> List&lt;HStoreFile&gt; sfs = new ArrayList&lt;&gt;(newFiles.size());</span>
<span class="source-line-no">7594</span><span id="line-7594"> final boolean evictOnClose =</span>
<span class="source-line-no">7595</span><span id="line-7595"> getCacheConfig() != null ? getCacheConfig().shouldEvictOnClose() : true;</span>
<span class="source-line-no">7596</span><span id="line-7596"> for (Path newFile : newFiles) {</span>
<span class="source-line-no">7597</span><span id="line-7597"> // Create storefile around what we wrote with a reader on it.</span>
<span class="source-line-no">7598</span><span id="line-7598"> HStoreFile sf = storeEngine.createStoreFileAndReader(newFile);</span>
<span class="source-line-no">7599</span><span id="line-7599"> sf.closeStoreFile(evictOnClose);</span>
<span class="source-line-no">7600</span><span id="line-7600"> sfs.add(sf);</span>
<span class="source-line-no">7601</span><span id="line-7601"> }</span>
<span class="source-line-no">7602</span><span id="line-7602"> return sfs;</span>
<span class="source-line-no">7603</span><span id="line-7603"> }</span>
<span class="source-line-no">7604</span><span id="line-7604"> return super.doCompaction(cr, filesToCompact, user, compactionStartTime, newFiles);</span>
<span class="source-line-no">7605</span><span id="line-7605"> }</span>
<span class="source-line-no">7606</span><span id="line-7606"> }</span>
<span class="source-line-no">7607</span><span id="line-7607"></span>
<span class="source-line-no">7608</span><span id="line-7608"> @Test</span>
<span class="source-line-no">7609</span><span id="line-7609"> public void testCloseNoInterrupt() throws Exception {</span>
<span class="source-line-no">7610</span><span id="line-7610"> byte[] cf1 = Bytes.toBytes("CF1");</span>
<span class="source-line-no">7611</span><span id="line-7611"> byte[][] families = { cf1 };</span>
<span class="source-line-no">7612</span><span id="line-7612"> final int SLEEP_TIME = 10 * 1000;</span>
<span class="source-line-no">7613</span><span id="line-7613"></span>
<span class="source-line-no">7614</span><span id="line-7614"> Configuration conf = new Configuration(CONF);</span>
<span class="source-line-no">7615</span><span id="line-7615"> // Disable close thread interrupt and server abort behavior</span>
<span class="source-line-no">7616</span><span id="line-7616"> conf.setBoolean(HRegion.CLOSE_WAIT_ABORT, false);</span>
<span class="source-line-no">7617</span><span id="line-7617"> conf.setInt(HRegion.CLOSE_WAIT_INTERVAL, 1000);</span>
<span class="source-line-no">7618</span><span id="line-7618"> region = initHRegion(tableName, method, conf, families);</span>
<span class="source-line-no">7619</span><span id="line-7619"></span>
<span class="source-line-no">7620</span><span id="line-7620"> final CountDownLatch latch = new CountDownLatch(1);</span>
<span class="source-line-no">7621</span><span id="line-7621"> final AtomicBoolean holderInterrupted = new AtomicBoolean();</span>
<span class="source-line-no">7622</span><span id="line-7622"> Thread holder = new Thread(new Runnable() {</span>
<span class="source-line-no">7623</span><span id="line-7623"> @Override</span>
<span class="source-line-no">7624</span><span id="line-7624"> public void run() {</span>
<span class="source-line-no">7625</span><span id="line-7625"> try {</span>
<span class="source-line-no">7626</span><span id="line-7626"> LOG.info("Starting region operation holder");</span>
<span class="source-line-no">7627</span><span id="line-7627"> region.startRegionOperation(Operation.SCAN);</span>
<span class="source-line-no">7628</span><span id="line-7628"> latch.countDown();</span>
<span class="source-line-no">7629</span><span id="line-7629"> try {</span>
<span class="source-line-no">7630</span><span id="line-7630"> Thread.sleep(SLEEP_TIME);</span>
<span class="source-line-no">7631</span><span id="line-7631"> } catch (InterruptedException e) {</span>
<span class="source-line-no">7632</span><span id="line-7632"> LOG.info("Interrupted");</span>
<span class="source-line-no">7633</span><span id="line-7633"> holderInterrupted.set(true);</span>
<span class="source-line-no">7634</span><span id="line-7634"> }</span>
<span class="source-line-no">7635</span><span id="line-7635"> } catch (Exception e) {</span>
<span class="source-line-no">7636</span><span id="line-7636"> throw new RuntimeException(e);</span>
<span class="source-line-no">7637</span><span id="line-7637"> } finally {</span>
<span class="source-line-no">7638</span><span id="line-7638"> try {</span>
<span class="source-line-no">7639</span><span id="line-7639"> region.closeRegionOperation();</span>
<span class="source-line-no">7640</span><span id="line-7640"> } catch (IOException e) {</span>
<span class="source-line-no">7641</span><span id="line-7641"> }</span>
<span class="source-line-no">7642</span><span id="line-7642"> LOG.info("Stopped region operation holder");</span>
<span class="source-line-no">7643</span><span id="line-7643"> }</span>
<span class="source-line-no">7644</span><span id="line-7644"> }</span>
<span class="source-line-no">7645</span><span id="line-7645"> });</span>
<span class="source-line-no">7646</span><span id="line-7646"></span>
<span class="source-line-no">7647</span><span id="line-7647"> holder.start();</span>
<span class="source-line-no">7648</span><span id="line-7648"> latch.await();</span>
<span class="source-line-no">7649</span><span id="line-7649"> HBaseTestingUtil.closeRegionAndWAL(region);</span>
<span class="source-line-no">7650</span><span id="line-7650"> region = null;</span>
<span class="source-line-no">7651</span><span id="line-7651"> holder.join();</span>
<span class="source-line-no">7652</span><span id="line-7652"></span>
<span class="source-line-no">7653</span><span id="line-7653"> assertFalse("Region lock holder should not have been interrupted", holderInterrupted.get());</span>
<span class="source-line-no">7654</span><span id="line-7654"> }</span>
<span class="source-line-no">7655</span><span id="line-7655"></span>
<span class="source-line-no">7656</span><span id="line-7656"> @Test</span>
<span class="source-line-no">7657</span><span id="line-7657"> public void testCloseInterrupt() throws Exception {</span>
<span class="source-line-no">7658</span><span id="line-7658"> byte[] cf1 = Bytes.toBytes("CF1");</span>
<span class="source-line-no">7659</span><span id="line-7659"> byte[][] families = { cf1 };</span>
<span class="source-line-no">7660</span><span id="line-7660"> final int SLEEP_TIME = 10 * 1000;</span>
<span class="source-line-no">7661</span><span id="line-7661"></span>
<span class="source-line-no">7662</span><span id="line-7662"> Configuration conf = new Configuration(CONF);</span>
<span class="source-line-no">7663</span><span id="line-7663"> // Enable close thread interrupt and server abort behavior</span>
<span class="source-line-no">7664</span><span id="line-7664"> conf.setBoolean(HRegion.CLOSE_WAIT_ABORT, true);</span>
<span class="source-line-no">7665</span><span id="line-7665"> // Speed up the unit test, no need to wait default 10 seconds.</span>
<span class="source-line-no">7666</span><span id="line-7666"> conf.setInt(HRegion.CLOSE_WAIT_INTERVAL, 1000);</span>
<span class="source-line-no">7667</span><span id="line-7667"> region = initHRegion(tableName, method, conf, families);</span>
<span class="source-line-no">7668</span><span id="line-7668"></span>
<span class="source-line-no">7669</span><span id="line-7669"> final CountDownLatch latch = new CountDownLatch(1);</span>
<span class="source-line-no">7670</span><span id="line-7670"> final AtomicBoolean holderInterrupted = new AtomicBoolean();</span>
<span class="source-line-no">7671</span><span id="line-7671"> Thread holder = new Thread(new Runnable() {</span>
<span class="source-line-no">7672</span><span id="line-7672"> @Override</span>
<span class="source-line-no">7673</span><span id="line-7673"> public void run() {</span>
<span class="source-line-no">7674</span><span id="line-7674"> try {</span>
<span class="source-line-no">7675</span><span id="line-7675"> LOG.info("Starting region operation holder");</span>
<span class="source-line-no">7676</span><span id="line-7676"> region.startRegionOperation(Operation.SCAN);</span>
<span class="source-line-no">7677</span><span id="line-7677"> latch.countDown();</span>
<span class="source-line-no">7678</span><span id="line-7678"> try {</span>
<span class="source-line-no">7679</span><span id="line-7679"> Thread.sleep(SLEEP_TIME);</span>
<span class="source-line-no">7680</span><span id="line-7680"> } catch (InterruptedException e) {</span>
<span class="source-line-no">7681</span><span id="line-7681"> LOG.info("Interrupted");</span>
<span class="source-line-no">7682</span><span id="line-7682"> holderInterrupted.set(true);</span>
<span class="source-line-no">7683</span><span id="line-7683"> }</span>
<span class="source-line-no">7684</span><span id="line-7684"> } catch (Exception e) {</span>
<span class="source-line-no">7685</span><span id="line-7685"> throw new RuntimeException(e);</span>
<span class="source-line-no">7686</span><span id="line-7686"> } finally {</span>
<span class="source-line-no">7687</span><span id="line-7687"> try {</span>
<span class="source-line-no">7688</span><span id="line-7688"> region.closeRegionOperation();</span>
<span class="source-line-no">7689</span><span id="line-7689"> } catch (IOException e) {</span>
<span class="source-line-no">7690</span><span id="line-7690"> }</span>
<span class="source-line-no">7691</span><span id="line-7691"> LOG.info("Stopped region operation holder");</span>
<span class="source-line-no">7692</span><span id="line-7692"> }</span>
<span class="source-line-no">7693</span><span id="line-7693"> }</span>
<span class="source-line-no">7694</span><span id="line-7694"> });</span>
<span class="source-line-no">7695</span><span id="line-7695"></span>
<span class="source-line-no">7696</span><span id="line-7696"> holder.start();</span>
<span class="source-line-no">7697</span><span id="line-7697"> latch.await();</span>
<span class="source-line-no">7698</span><span id="line-7698"> region.close();</span>
<span class="source-line-no">7699</span><span id="line-7699"> region = null;</span>
<span class="source-line-no">7700</span><span id="line-7700"> holder.join();</span>
<span class="source-line-no">7701</span><span id="line-7701"></span>
<span class="source-line-no">7702</span><span id="line-7702"> assertTrue("Region lock holder was not interrupted", holderInterrupted.get());</span>
<span class="source-line-no">7703</span><span id="line-7703"> }</span>
<span class="source-line-no">7704</span><span id="line-7704"></span>
<span class="source-line-no">7705</span><span id="line-7705"> @Test</span>
<span class="source-line-no">7706</span><span id="line-7706"> public void testCloseAbort() throws Exception {</span>
<span class="source-line-no">7707</span><span id="line-7707"> byte[] cf1 = Bytes.toBytes("CF1");</span>
<span class="source-line-no">7708</span><span id="line-7708"> byte[][] families = { cf1 };</span>
<span class="source-line-no">7709</span><span id="line-7709"> final int SLEEP_TIME = 10 * 1000;</span>
<span class="source-line-no">7710</span><span id="line-7710"></span>
<span class="source-line-no">7711</span><span id="line-7711"> Configuration conf = new Configuration(CONF);</span>
<span class="source-line-no">7712</span><span id="line-7712"> // Enable close thread interrupt and server abort behavior.</span>
<span class="source-line-no">7713</span><span id="line-7713"> conf.setBoolean(HRegion.CLOSE_WAIT_ABORT, true);</span>
<span class="source-line-no">7714</span><span id="line-7714"> // Set the abort interval to a fraction of sleep time so we are guaranteed to be aborted.</span>
<span class="source-line-no">7715</span><span id="line-7715"> conf.setInt(HRegion.CLOSE_WAIT_TIME, SLEEP_TIME / 2);</span>
<span class="source-line-no">7716</span><span id="line-7716"> // Set the wait interval to a fraction of sleep time so we are guaranteed to be interrupted.</span>
<span class="source-line-no">7717</span><span id="line-7717"> conf.setInt(HRegion.CLOSE_WAIT_INTERVAL, SLEEP_TIME / 4);</span>
<span class="source-line-no">7718</span><span id="line-7718"> region = initHRegion(tableName, method, conf, families);</span>
<span class="source-line-no">7719</span><span id="line-7719"> RegionServerServices rsServices = mock(RegionServerServices.class);</span>
<span class="source-line-no">7720</span><span id="line-7720"> when(rsServices.getServerName()).thenReturn(ServerName.valueOf("localhost", 1000, 1000));</span>
<span class="source-line-no">7721</span><span id="line-7721"> region.rsServices = rsServices;</span>
<span class="source-line-no">7722</span><span id="line-7722"></span>
<span class="source-line-no">7723</span><span id="line-7723"> final CountDownLatch latch = new CountDownLatch(1);</span>
<span class="source-line-no">7724</span><span id="line-7724"> Thread holder = new Thread(new Runnable() {</span>
<span class="source-line-no">7725</span><span id="line-7725"> @Override</span>
<span class="source-line-no">7726</span><span id="line-7726"> public void run() {</span>
<span class="source-line-no">7727</span><span id="line-7727"> try {</span>
<span class="source-line-no">7728</span><span id="line-7728"> LOG.info("Starting region operation holder");</span>
<span class="source-line-no">7729</span><span id="line-7729"> region.startRegionOperation(Operation.SCAN);</span>
<span class="source-line-no">7730</span><span id="line-7730"> latch.countDown();</span>
<span class="source-line-no">7731</span><span id="line-7731"> // Hold the lock for SLEEP_TIME seconds no matter how many times we are interrupted.</span>
<span class="source-line-no">7732</span><span id="line-7732"> int timeRemaining = SLEEP_TIME;</span>
<span class="source-line-no">7733</span><span id="line-7733"> while (timeRemaining &gt; 0) {</span>
<span class="source-line-no">7734</span><span id="line-7734"> long start = EnvironmentEdgeManager.currentTime();</span>
<span class="source-line-no">7735</span><span id="line-7735"> try {</span>
<span class="source-line-no">7736</span><span id="line-7736"> Thread.sleep(timeRemaining);</span>
<span class="source-line-no">7737</span><span id="line-7737"> } catch (InterruptedException e) {</span>
<span class="source-line-no">7738</span><span id="line-7738"> LOG.info("Interrupted");</span>
<span class="source-line-no">7739</span><span id="line-7739"> }</span>
<span class="source-line-no">7740</span><span id="line-7740"> long end = EnvironmentEdgeManager.currentTime();</span>
<span class="source-line-no">7741</span><span id="line-7741"> timeRemaining -= end - start;</span>
<span class="source-line-no">7742</span><span id="line-7742"> if (timeRemaining &lt; 0) {</span>
<span class="source-line-no">7743</span><span id="line-7743"> timeRemaining = 0;</span>
<span class="source-line-no">7744</span><span id="line-7744"> }</span>
<span class="source-line-no">7745</span><span id="line-7745"> if (timeRemaining &gt; 0) {</span>
<span class="source-line-no">7746</span><span id="line-7746"> LOG.info("Sleeping again, remaining time " + timeRemaining + " ms");</span>
<span class="source-line-no">7747</span><span id="line-7747"> }</span>
<span class="source-line-no">7748</span><span id="line-7748"> }</span>
<span class="source-line-no">7749</span><span id="line-7749"> } catch (Exception e) {</span>
<span class="source-line-no">7750</span><span id="line-7750"> throw new RuntimeException(e);</span>
<span class="source-line-no">7751</span><span id="line-7751"> } finally {</span>
<span class="source-line-no">7752</span><span id="line-7752"> try {</span>
<span class="source-line-no">7753</span><span id="line-7753"> region.closeRegionOperation();</span>
<span class="source-line-no">7754</span><span id="line-7754"> } catch (IOException e) {</span>
<span class="source-line-no">7755</span><span id="line-7755"> }</span>
<span class="source-line-no">7756</span><span id="line-7756"> LOG.info("Stopped region operation holder");</span>
<span class="source-line-no">7757</span><span id="line-7757"> }</span>
<span class="source-line-no">7758</span><span id="line-7758"> }</span>
<span class="source-line-no">7759</span><span id="line-7759"> });</span>
<span class="source-line-no">7760</span><span id="line-7760"></span>
<span class="source-line-no">7761</span><span id="line-7761"> holder.start();</span>
<span class="source-line-no">7762</span><span id="line-7762"> latch.await();</span>
<span class="source-line-no">7763</span><span id="line-7763"> assertThrows(IOException.class, () -&gt; region.close());</span>
<span class="source-line-no">7764</span><span id="line-7764"> holder.join();</span>
<span class="source-line-no">7765</span><span id="line-7765"></span>
<span class="source-line-no">7766</span><span id="line-7766"> // Verify the region tried to abort the server</span>
<span class="source-line-no">7767</span><span id="line-7767"> verify(rsServices, atLeast(1)).abort(anyString(), any());</span>
<span class="source-line-no">7768</span><span id="line-7768"> }</span>
<span class="source-line-no">7769</span><span id="line-7769"></span>
<span class="source-line-no">7770</span><span id="line-7770"> @Test</span>
<span class="source-line-no">7771</span><span id="line-7771"> public void testInterruptProtection() throws Exception {</span>
<span class="source-line-no">7772</span><span id="line-7772"> byte[] cf1 = Bytes.toBytes("CF1");</span>
<span class="source-line-no">7773</span><span id="line-7773"> byte[][] families = { cf1 };</span>
<span class="source-line-no">7774</span><span id="line-7774"> final int SLEEP_TIME = 10 * 1000;</span>
<span class="source-line-no">7775</span><span id="line-7775"></span>
<span class="source-line-no">7776</span><span id="line-7776"> Configuration conf = new Configuration(CONF);</span>
<span class="source-line-no">7777</span><span id="line-7777"> // Enable close thread interrupt and server abort behavior.</span>
<span class="source-line-no">7778</span><span id="line-7778"> conf.setBoolean(HRegion.CLOSE_WAIT_ABORT, true);</span>
<span class="source-line-no">7779</span><span id="line-7779"> conf.setInt(HRegion.CLOSE_WAIT_INTERVAL, 1000);</span>
<span class="source-line-no">7780</span><span id="line-7780"> region = initHRegion(tableName, method, conf, families);</span>
<span class="source-line-no">7781</span><span id="line-7781"></span>
<span class="source-line-no">7782</span><span id="line-7782"> final CountDownLatch latch = new CountDownLatch(1);</span>
<span class="source-line-no">7783</span><span id="line-7783"> final AtomicBoolean holderInterrupted = new AtomicBoolean();</span>
<span class="source-line-no">7784</span><span id="line-7784"> Thread holder = new Thread(new Runnable() {</span>
<span class="source-line-no">7785</span><span id="line-7785"> @Override</span>
<span class="source-line-no">7786</span><span id="line-7786"> public void run() {</span>
<span class="source-line-no">7787</span><span id="line-7787"> try {</span>
<span class="source-line-no">7788</span><span id="line-7788"> LOG.info("Starting region operation holder");</span>
<span class="source-line-no">7789</span><span id="line-7789"> region.startRegionOperation(Operation.SCAN);</span>
<span class="source-line-no">7790</span><span id="line-7790"> LOG.info("Protecting against interrupts");</span>
<span class="source-line-no">7791</span><span id="line-7791"> region.disableInterrupts();</span>
<span class="source-line-no">7792</span><span id="line-7792"> try {</span>
<span class="source-line-no">7793</span><span id="line-7793"> latch.countDown();</span>
<span class="source-line-no">7794</span><span id="line-7794"> try {</span>
<span class="source-line-no">7795</span><span id="line-7795"> Thread.sleep(SLEEP_TIME);</span>
<span class="source-line-no">7796</span><span id="line-7796"> } catch (InterruptedException e) {</span>
<span class="source-line-no">7797</span><span id="line-7797"> LOG.info("Interrupted");</span>
<span class="source-line-no">7798</span><span id="line-7798"> holderInterrupted.set(true);</span>
<span class="source-line-no">7799</span><span id="line-7799"> }</span>
<span class="source-line-no">7800</span><span id="line-7800"> } finally {</span>
<span class="source-line-no">7801</span><span id="line-7801"> region.enableInterrupts();</span>
<span class="source-line-no">7802</span><span id="line-7802"> }</span>
<span class="source-line-no">7803</span><span id="line-7803"> } catch (Exception e) {</span>
<span class="source-line-no">7804</span><span id="line-7804"> throw new RuntimeException(e);</span>
<span class="source-line-no">7805</span><span id="line-7805"> } finally {</span>
<span class="source-line-no">7806</span><span id="line-7806"> try {</span>
<span class="source-line-no">7807</span><span id="line-7807"> region.closeRegionOperation();</span>
<span class="source-line-no">7808</span><span id="line-7808"> } catch (IOException e) {</span>
<span class="source-line-no">7809</span><span id="line-7809"> }</span>
<span class="source-line-no">7810</span><span id="line-7810"> LOG.info("Stopped region operation holder");</span>
<span class="source-line-no">7811</span><span id="line-7811"> }</span>
<span class="source-line-no">7812</span><span id="line-7812"> }</span>
<span class="source-line-no">7813</span><span id="line-7813"> });</span>
<span class="source-line-no">7814</span><span id="line-7814"></span>
<span class="source-line-no">7815</span><span id="line-7815"> holder.start();</span>
<span class="source-line-no">7816</span><span id="line-7816"> latch.await();</span>
<span class="source-line-no">7817</span><span id="line-7817"> region.close();</span>
<span class="source-line-no">7818</span><span id="line-7818"> region = null;</span>
<span class="source-line-no">7819</span><span id="line-7819"> holder.join();</span>
<span class="source-line-no">7820</span><span id="line-7820"></span>
<span class="source-line-no">7821</span><span id="line-7821"> assertFalse("Region lock holder should not have been interrupted", holderInterrupted.get());</span>
<span class="source-line-no">7822</span><span id="line-7822"> }</span>
<span class="source-line-no">7823</span><span id="line-7823"></span>
<span class="source-line-no">7824</span><span id="line-7824"> @Test</span>
<span class="source-line-no">7825</span><span id="line-7825"> public void testRegionOnCoprocessorsChange() throws IOException {</span>
<span class="source-line-no">7826</span><span id="line-7826"> byte[] cf1 = Bytes.toBytes("CF1");</span>
<span class="source-line-no">7827</span><span id="line-7827"> byte[][] families = { cf1 };</span>
<span class="source-line-no">7828</span><span id="line-7828"></span>
<span class="source-line-no">7829</span><span id="line-7829"> Configuration conf = new Configuration(CONF);</span>
<span class="source-line-no">7830</span><span id="line-7830"> region = initHRegion(tableName, method, conf, families);</span>
<span class="source-line-no">7831</span><span id="line-7831"> assertNull(region.getCoprocessorHost());</span>
<span class="source-line-no">7832</span><span id="line-7832"></span>
<span class="source-line-no">7833</span><span id="line-7833"> // set and verify the system coprocessors for region and user region</span>
<span class="source-line-no">7834</span><span id="line-7834"> Configuration newConf = new Configuration(conf);</span>
<span class="source-line-no">7835</span><span id="line-7835"> newConf.set(CoprocessorHost.REGION_COPROCESSOR_CONF_KEY, MetaTableMetrics.class.getName());</span>
<span class="source-line-no">7836</span><span id="line-7836"> newConf.set(CoprocessorHost.USER_REGION_COPROCESSOR_CONF_KEY,</span>
<span class="source-line-no">7837</span><span id="line-7837"> NoOpRegionCoprocessor.class.getName());</span>
<span class="source-line-no">7838</span><span id="line-7838"> // trigger configuration change</span>
<span class="source-line-no">7839</span><span id="line-7839"> region.onConfigurationChange(newConf);</span>
<span class="source-line-no">7840</span><span id="line-7840"> assertTrue(region.getCoprocessorHost() != null);</span>
<span class="source-line-no">7841</span><span id="line-7841"> Set&lt;String&gt; coprocessors = region.getCoprocessorHost().getCoprocessors();</span>
<span class="source-line-no">7842</span><span id="line-7842"> assertTrue(coprocessors.size() == 2);</span>
<span class="source-line-no">7843</span><span id="line-7843"> assertTrue(region.getCoprocessorHost().getCoprocessors()</span>
<span class="source-line-no">7844</span><span id="line-7844"> .contains(MetaTableMetrics.class.getSimpleName()));</span>
<span class="source-line-no">7845</span><span id="line-7845"> assertTrue(region.getCoprocessorHost().getCoprocessors()</span>
<span class="source-line-no">7846</span><span id="line-7846"> .contains(NoOpRegionCoprocessor.class.getSimpleName()));</span>
<span class="source-line-no">7847</span><span id="line-7847"></span>
<span class="source-line-no">7848</span><span id="line-7848"> // remove region coprocessor and keep only user region coprocessor</span>
<span class="source-line-no">7849</span><span id="line-7849"> newConf.unset(CoprocessorHost.REGION_COPROCESSOR_CONF_KEY);</span>
<span class="source-line-no">7850</span><span id="line-7850"> region.onConfigurationChange(newConf);</span>
<span class="source-line-no">7851</span><span id="line-7851"> assertTrue(region.getCoprocessorHost() != null);</span>
<span class="source-line-no">7852</span><span id="line-7852"> coprocessors = region.getCoprocessorHost().getCoprocessors();</span>
<span class="source-line-no">7853</span><span id="line-7853"> assertTrue(coprocessors.size() == 1);</span>
<span class="source-line-no">7854</span><span id="line-7854"> assertTrue(region.getCoprocessorHost().getCoprocessors()</span>
<span class="source-line-no">7855</span><span id="line-7855"> .contains(NoOpRegionCoprocessor.class.getSimpleName()));</span>
<span class="source-line-no">7856</span><span id="line-7856"> }</span>
<span class="source-line-no">7857</span><span id="line-7857"></span>
<span class="source-line-no">7858</span><span id="line-7858"> @Test</span>
<span class="source-line-no">7859</span><span id="line-7859"> public void testRegionOnCoprocessorsWithoutChange() throws IOException {</span>
<span class="source-line-no">7860</span><span id="line-7860"> byte[] cf1 = Bytes.toBytes("CF1");</span>
<span class="source-line-no">7861</span><span id="line-7861"> byte[][] families = { cf1 };</span>
<span class="source-line-no">7862</span><span id="line-7862"></span>
<span class="source-line-no">7863</span><span id="line-7863"> Configuration conf = new Configuration(CONF);</span>
<span class="source-line-no">7864</span><span id="line-7864"> conf.set(CoprocessorHost.REGION_COPROCESSOR_CONF_KEY,</span>
<span class="source-line-no">7865</span><span id="line-7865"> MetaTableMetrics.class.getCanonicalName());</span>
<span class="source-line-no">7866</span><span id="line-7866"> region = initHRegion(tableName, method, conf, families);</span>
<span class="source-line-no">7867</span><span id="line-7867"> // region service is null in unit test, we need to load the coprocessor once</span>
<span class="source-line-no">7868</span><span id="line-7868"> region.setCoprocessorHost(new RegionCoprocessorHost(region, null, conf));</span>
<span class="source-line-no">7869</span><span id="line-7869"> RegionCoprocessor regionCoprocessor =</span>
<span class="source-line-no">7870</span><span id="line-7870"> region.getCoprocessorHost().findCoprocessor(MetaTableMetrics.class.getName());</span>
<span class="source-line-no">7871</span><span id="line-7871"></span>
<span class="source-line-no">7872</span><span id="line-7872"> // simulate when other configuration may have changed and onConfigurationChange execute once</span>
<span class="source-line-no">7873</span><span id="line-7873"> region.onConfigurationChange(conf);</span>
<span class="source-line-no">7874</span><span id="line-7874"> RegionCoprocessor regionCoprocessorAfterOnConfigurationChange =</span>
<span class="source-line-no">7875</span><span id="line-7875"> region.getCoprocessorHost().findCoprocessor(MetaTableMetrics.class.getName());</span>
<span class="source-line-no">7876</span><span id="line-7876"> assertEquals(regionCoprocessor, regionCoprocessorAfterOnConfigurationChange);</span>
<span class="source-line-no">7877</span><span id="line-7877"> }</span>
<span class="source-line-no">7878</span><span id="line-7878"></span>
<span class="source-line-no">7879</span><span id="line-7879"> public static class NoOpRegionCoprocessor implements RegionCoprocessor, RegionObserver {</span>
<span class="source-line-no">7880</span><span id="line-7880"> // a empty region coprocessor class</span>
<span class="source-line-no">7881</span><span id="line-7881"> }</span>
<span class="source-line-no">7882</span><span id="line-7882">}</span>
</pre>
</div>
</main>
</body>
</html>