blob: 8cd91b7e54502c1d9c2064938309b77d61f77d86 [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: PutThread">
<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.ClientInternalHelper;</span>
<span class="source-line-no">110</span><span id="line-110">import org.apache.hadoop.hbase.client.ColumnFamilyDescriptor;</span>
<span class="source-line-no">111</span><span id="line-111">import org.apache.hadoop.hbase.client.ColumnFamilyDescriptorBuilder;</span>
<span class="source-line-no">112</span><span id="line-112">import org.apache.hadoop.hbase.client.Delete;</span>
<span class="source-line-no">113</span><span id="line-113">import org.apache.hadoop.hbase.client.Durability;</span>
<span class="source-line-no">114</span><span id="line-114">import org.apache.hadoop.hbase.client.Get;</span>
<span class="source-line-no">115</span><span id="line-115">import org.apache.hadoop.hbase.client.Increment;</span>
<span class="source-line-no">116</span><span id="line-116">import org.apache.hadoop.hbase.client.Mutation;</span>
<span class="source-line-no">117</span><span id="line-117">import org.apache.hadoop.hbase.client.Put;</span>
<span class="source-line-no">118</span><span id="line-118">import org.apache.hadoop.hbase.client.RegionInfo;</span>
<span class="source-line-no">119</span><span id="line-119">import org.apache.hadoop.hbase.client.RegionInfoBuilder;</span>
<span class="source-line-no">120</span><span id="line-120">import org.apache.hadoop.hbase.client.Result;</span>
<span class="source-line-no">121</span><span id="line-121">import org.apache.hadoop.hbase.client.RowMutations;</span>
<span class="source-line-no">122</span><span id="line-122">import org.apache.hadoop.hbase.client.Scan;</span>
<span class="source-line-no">123</span><span id="line-123">import org.apache.hadoop.hbase.client.Table;</span>
<span class="source-line-no">124</span><span id="line-124">import org.apache.hadoop.hbase.client.TableDescriptor;</span>
<span class="source-line-no">125</span><span id="line-125">import org.apache.hadoop.hbase.client.TableDescriptorBuilder;</span>
<span class="source-line-no">126</span><span id="line-126">import org.apache.hadoop.hbase.coprocessor.CoprocessorHost;</span>
<span class="source-line-no">127</span><span id="line-127">import org.apache.hadoop.hbase.coprocessor.MetaTableMetrics;</span>
<span class="source-line-no">128</span><span id="line-128">import org.apache.hadoop.hbase.coprocessor.RegionCoprocessor;</span>
<span class="source-line-no">129</span><span id="line-129">import org.apache.hadoop.hbase.coprocessor.RegionObserver;</span>
<span class="source-line-no">130</span><span id="line-130">import org.apache.hadoop.hbase.exceptions.FailedSanityCheckException;</span>
<span class="source-line-no">131</span><span id="line-131">import org.apache.hadoop.hbase.filter.BigDecimalComparator;</span>
<span class="source-line-no">132</span><span id="line-132">import org.apache.hadoop.hbase.filter.BinaryComparator;</span>
<span class="source-line-no">133</span><span id="line-133">import org.apache.hadoop.hbase.filter.ColumnCountGetFilter;</span>
<span class="source-line-no">134</span><span id="line-134">import org.apache.hadoop.hbase.filter.Filter;</span>
<span class="source-line-no">135</span><span id="line-135">import org.apache.hadoop.hbase.filter.FilterBase;</span>
<span class="source-line-no">136</span><span id="line-136">import org.apache.hadoop.hbase.filter.FilterList;</span>
<span class="source-line-no">137</span><span id="line-137">import org.apache.hadoop.hbase.filter.NullComparator;</span>
<span class="source-line-no">138</span><span id="line-138">import org.apache.hadoop.hbase.filter.PrefixFilter;</span>
<span class="source-line-no">139</span><span id="line-139">import org.apache.hadoop.hbase.filter.SingleColumnValueExcludeFilter;</span>
<span class="source-line-no">140</span><span id="line-140">import org.apache.hadoop.hbase.filter.SingleColumnValueFilter;</span>
<span class="source-line-no">141</span><span id="line-141">import org.apache.hadoop.hbase.filter.SubstringComparator;</span>
<span class="source-line-no">142</span><span id="line-142">import org.apache.hadoop.hbase.filter.ValueFilter;</span>
<span class="source-line-no">143</span><span id="line-143">import org.apache.hadoop.hbase.io.TimeRange;</span>
<span class="source-line-no">144</span><span id="line-144">import org.apache.hadoop.hbase.io.hfile.HFile;</span>
<span class="source-line-no">145</span><span id="line-145">import org.apache.hadoop.hbase.monitoring.MonitoredRPCHandler;</span>
<span class="source-line-no">146</span><span id="line-146">import org.apache.hadoop.hbase.monitoring.MonitoredTask;</span>
<span class="source-line-no">147</span><span id="line-147">import org.apache.hadoop.hbase.monitoring.TaskMonitor;</span>
<span class="source-line-no">148</span><span id="line-148">import org.apache.hadoop.hbase.regionserver.Region.Operation;</span>
<span class="source-line-no">149</span><span id="line-149">import org.apache.hadoop.hbase.regionserver.Region.RowLock;</span>
<span class="source-line-no">150</span><span id="line-150">import org.apache.hadoop.hbase.regionserver.TestHStore.FaultyFileSystem;</span>
<span class="source-line-no">151</span><span id="line-151">import org.apache.hadoop.hbase.regionserver.compactions.CompactionRequestImpl;</span>
<span class="source-line-no">152</span><span id="line-152">import org.apache.hadoop.hbase.regionserver.wal.AbstractFSWAL;</span>
<span class="source-line-no">153</span><span id="line-153">import org.apache.hadoop.hbase.regionserver.wal.AsyncFSWAL;</span>
<span class="source-line-no">154</span><span id="line-154">import org.apache.hadoop.hbase.regionserver.wal.FSHLog;</span>
<span class="source-line-no">155</span><span id="line-155">import org.apache.hadoop.hbase.regionserver.wal.MetricsWALSource;</span>
<span class="source-line-no">156</span><span id="line-156">import org.apache.hadoop.hbase.regionserver.wal.WALUtil;</span>
<span class="source-line-no">157</span><span id="line-157">import org.apache.hadoop.hbase.replication.regionserver.ReplicationObserver;</span>
<span class="source-line-no">158</span><span id="line-158">import org.apache.hadoop.hbase.security.User;</span>
<span class="source-line-no">159</span><span id="line-159">import org.apache.hadoop.hbase.test.MetricsAssertHelper;</span>
<span class="source-line-no">160</span><span id="line-160">import org.apache.hadoop.hbase.testclassification.LargeTests;</span>
<span class="source-line-no">161</span><span id="line-161">import org.apache.hadoop.hbase.testclassification.VerySlowRegionServerTests;</span>
<span class="source-line-no">162</span><span id="line-162">import org.apache.hadoop.hbase.util.Bytes;</span>
<span class="source-line-no">163</span><span id="line-163">import org.apache.hadoop.hbase.util.CommonFSUtils;</span>
<span class="source-line-no">164</span><span id="line-164">import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;</span>
<span class="source-line-no">165</span><span id="line-165">import org.apache.hadoop.hbase.util.EnvironmentEdgeManagerTestHelper;</span>
<span class="source-line-no">166</span><span id="line-166">import org.apache.hadoop.hbase.util.HFileArchiveUtil;</span>
<span class="source-line-no">167</span><span id="line-167">import org.apache.hadoop.hbase.util.IncrementingEnvironmentEdge;</span>
<span class="source-line-no">168</span><span id="line-168">import org.apache.hadoop.hbase.util.ManualEnvironmentEdge;</span>
<span class="source-line-no">169</span><span id="line-169">import org.apache.hadoop.hbase.util.Threads;</span>
<span class="source-line-no">170</span><span id="line-170">import org.apache.hadoop.hbase.wal.AbstractFSWALProvider;</span>
<span class="source-line-no">171</span><span id="line-171">import org.apache.hadoop.hbase.wal.FaultyFSLog;</span>
<span class="source-line-no">172</span><span id="line-172">import org.apache.hadoop.hbase.wal.NettyAsyncFSWALConfigHelper;</span>
<span class="source-line-no">173</span><span id="line-173">import org.apache.hadoop.hbase.wal.WAL;</span>
<span class="source-line-no">174</span><span id="line-174">import org.apache.hadoop.hbase.wal.WALEdit;</span>
<span class="source-line-no">175</span><span id="line-175">import org.apache.hadoop.hbase.wal.WALEditInternalHelper;</span>
<span class="source-line-no">176</span><span id="line-176">import org.apache.hadoop.hbase.wal.WALFactory;</span>
<span class="source-line-no">177</span><span id="line-177">import org.apache.hadoop.hbase.wal.WALKeyImpl;</span>
<span class="source-line-no">178</span><span id="line-178">import org.apache.hadoop.hbase.wal.WALProvider;</span>
<span class="source-line-no">179</span><span id="line-179">import org.apache.hadoop.hbase.wal.WALProvider.Writer;</span>
<span class="source-line-no">180</span><span id="line-180">import org.apache.hadoop.hbase.wal.WALSplitUtil;</span>
<span class="source-line-no">181</span><span id="line-181">import org.apache.hadoop.hbase.wal.WALStreamReader;</span>
<span class="source-line-no">182</span><span id="line-182">import org.junit.After;</span>
<span class="source-line-no">183</span><span id="line-183">import org.junit.Assert;</span>
<span class="source-line-no">184</span><span id="line-184">import org.junit.Before;</span>
<span class="source-line-no">185</span><span id="line-185">import org.junit.ClassRule;</span>
<span class="source-line-no">186</span><span id="line-186">import org.junit.Ignore;</span>
<span class="source-line-no">187</span><span id="line-187">import org.junit.Rule;</span>
<span class="source-line-no">188</span><span id="line-188">import org.junit.Test;</span>
<span class="source-line-no">189</span><span id="line-189">import org.junit.experimental.categories.Category;</span>
<span class="source-line-no">190</span><span id="line-190">import org.junit.rules.ExpectedException;</span>
<span class="source-line-no">191</span><span id="line-191">import org.junit.rules.TestName;</span>
<span class="source-line-no">192</span><span id="line-192">import org.mockito.ArgumentCaptor;</span>
<span class="source-line-no">193</span><span id="line-193">import org.mockito.ArgumentMatcher;</span>
<span class="source-line-no">194</span><span id="line-194">import org.mockito.invocation.InvocationOnMock;</span>
<span class="source-line-no">195</span><span id="line-195">import org.mockito.stubbing.Answer;</span>
<span class="source-line-no">196</span><span id="line-196">import org.slf4j.Logger;</span>
<span class="source-line-no">197</span><span id="line-197">import org.slf4j.LoggerFactory;</span>
<span class="source-line-no">198</span><span id="line-198"></span>
<span class="source-line-no">199</span><span id="line-199">import org.apache.hbase.thirdparty.com.google.common.collect.Lists;</span>
<span class="source-line-no">200</span><span id="line-200">import org.apache.hbase.thirdparty.com.google.protobuf.ByteString;</span>
<span class="source-line-no">201</span><span id="line-201">import org.apache.hbase.thirdparty.io.netty.channel.EventLoopGroup;</span>
<span class="source-line-no">202</span><span id="line-202">import org.apache.hbase.thirdparty.io.netty.channel.nio.NioEventLoopGroup;</span>
<span class="source-line-no">203</span><span id="line-203">import org.apache.hbase.thirdparty.io.netty.channel.socket.nio.NioSocketChannel;</span>
<span class="source-line-no">204</span><span id="line-204"></span>
<span class="source-line-no">205</span><span id="line-205">import org.apache.hadoop.hbase.shaded.protobuf.ProtobufUtil;</span>
<span class="source-line-no">206</span><span id="line-206">import org.apache.hadoop.hbase.shaded.protobuf.generated.WALProtos.CompactionDescriptor;</span>
<span class="source-line-no">207</span><span id="line-207">import org.apache.hadoop.hbase.shaded.protobuf.generated.WALProtos.FlushDescriptor;</span>
<span class="source-line-no">208</span><span id="line-208">import org.apache.hadoop.hbase.shaded.protobuf.generated.WALProtos.FlushDescriptor.FlushAction;</span>
<span class="source-line-no">209</span><span id="line-209">import org.apache.hadoop.hbase.shaded.protobuf.generated.WALProtos.FlushDescriptor.StoreFlushDescriptor;</span>
<span class="source-line-no">210</span><span id="line-210">import org.apache.hadoop.hbase.shaded.protobuf.generated.WALProtos.RegionEventDescriptor;</span>
<span class="source-line-no">211</span><span id="line-211">import org.apache.hadoop.hbase.shaded.protobuf.generated.WALProtos.StoreDescriptor;</span>
<span class="source-line-no">212</span><span id="line-212"></span>
<span class="source-line-no">213</span><span id="line-213">/**</span>
<span class="source-line-no">214</span><span id="line-214"> * Basic stand-alone testing of HRegion. No clusters! A lot of the meta information for an HRegion</span>
<span class="source-line-no">215</span><span id="line-215"> * now lives inside other HRegions or in the HBaseMaster, so only basic testing is possible.</span>
<span class="source-line-no">216</span><span id="line-216"> */</span>
<span class="source-line-no">217</span><span id="line-217">@Category({ VerySlowRegionServerTests.class, LargeTests.class })</span>
<span class="source-line-no">218</span><span id="line-218">@SuppressWarnings("deprecation")</span>
<span class="source-line-no">219</span><span id="line-219">public class TestHRegion {</span>
<span class="source-line-no">220</span><span id="line-220"></span>
<span class="source-line-no">221</span><span id="line-221"> @ClassRule</span>
<span class="source-line-no">222</span><span id="line-222"> public static final HBaseClassTestRule CLASS_RULE =</span>
<span class="source-line-no">223</span><span id="line-223"> HBaseClassTestRule.forClass(TestHRegion.class);</span>
<span class="source-line-no">224</span><span id="line-224"></span>
<span class="source-line-no">225</span><span id="line-225"> // Do not spin up clusters in here. If you need to spin up a cluster, do it</span>
<span class="source-line-no">226</span><span id="line-226"> // over in TestHRegionOnCluster.</span>
<span class="source-line-no">227</span><span id="line-227"> private static final Logger LOG = LoggerFactory.getLogger(TestHRegion.class);</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 TestName name = new TestName();</span>
<span class="source-line-no">230</span><span id="line-230"> @Rule</span>
<span class="source-line-no">231</span><span id="line-231"> public final ExpectedException thrown = ExpectedException.none();</span>
<span class="source-line-no">232</span><span id="line-232"></span>
<span class="source-line-no">233</span><span id="line-233"> private static final String COLUMN_FAMILY = "MyCF";</span>
<span class="source-line-no">234</span><span id="line-234"> private static final byte[] COLUMN_FAMILY_BYTES = Bytes.toBytes(COLUMN_FAMILY);</span>
<span class="source-line-no">235</span><span id="line-235"> private static final EventLoopGroup GROUP = new NioEventLoopGroup();</span>
<span class="source-line-no">236</span><span id="line-236"></span>
<span class="source-line-no">237</span><span id="line-237"> HRegion region = null;</span>
<span class="source-line-no">238</span><span id="line-238"> // Do not run unit tests in parallel (? Why not? It don't work? Why not? St.Ack)</span>
<span class="source-line-no">239</span><span id="line-239"> protected static HBaseTestingUtil TEST_UTIL;</span>
<span class="source-line-no">240</span><span id="line-240"> public static Configuration CONF;</span>
<span class="source-line-no">241</span><span id="line-241"> private String dir;</span>
<span class="source-line-no">242</span><span id="line-242"> private final int MAX_VERSIONS = 2;</span>
<span class="source-line-no">243</span><span id="line-243"></span>
<span class="source-line-no">244</span><span id="line-244"> // Test names</span>
<span class="source-line-no">245</span><span id="line-245"> protected TableName tableName;</span>
<span class="source-line-no">246</span><span id="line-246"> protected String method;</span>
<span class="source-line-no">247</span><span id="line-247"> protected final byte[] qual = Bytes.toBytes("qual");</span>
<span class="source-line-no">248</span><span id="line-248"> protected final byte[] qual1 = Bytes.toBytes("qual1");</span>
<span class="source-line-no">249</span><span id="line-249"> protected final byte[] qual2 = Bytes.toBytes("qual2");</span>
<span class="source-line-no">250</span><span id="line-250"> protected final byte[] qual3 = Bytes.toBytes("qual3");</span>
<span class="source-line-no">251</span><span id="line-251"> protected final byte[] value = Bytes.toBytes("value");</span>
<span class="source-line-no">252</span><span id="line-252"> protected final byte[] value1 = Bytes.toBytes("value1");</span>
<span class="source-line-no">253</span><span id="line-253"> protected final byte[] value2 = Bytes.toBytes("value2");</span>
<span class="source-line-no">254</span><span id="line-254"> protected final byte[] row = Bytes.toBytes("rowA");</span>
<span class="source-line-no">255</span><span id="line-255"> protected final byte[] row2 = Bytes.toBytes("rowB");</span>
<span class="source-line-no">256</span><span id="line-256"></span>
<span class="source-line-no">257</span><span id="line-257"> protected final MetricsAssertHelper metricsAssertHelper =</span>
<span class="source-line-no">258</span><span id="line-258"> CompatibilitySingletonFactory.getInstance(MetricsAssertHelper.class);</span>
<span class="source-line-no">259</span><span id="line-259"></span>
<span class="source-line-no">260</span><span id="line-260"> @Before</span>
<span class="source-line-no">261</span><span id="line-261"> public void setup() throws IOException {</span>
<span class="source-line-no">262</span><span id="line-262"> TEST_UTIL = new HBaseTestingUtil();</span>
<span class="source-line-no">263</span><span id="line-263"> CONF = TEST_UTIL.getConfiguration();</span>
<span class="source-line-no">264</span><span id="line-264"> NettyAsyncFSWALConfigHelper.setEventLoopConfig(CONF, GROUP, NioSocketChannel.class);</span>
<span class="source-line-no">265</span><span id="line-265"> dir = TEST_UTIL.getDataTestDir("TestHRegion").toString();</span>
<span class="source-line-no">266</span><span id="line-266"> method = name.getMethodName();</span>
<span class="source-line-no">267</span><span id="line-267"> tableName = TableName.valueOf(method);</span>
<span class="source-line-no">268</span><span id="line-268"> CONF.set(CompactingMemStore.IN_MEMORY_FLUSH_THRESHOLD_FACTOR_KEY, String.valueOf(0.09));</span>
<span class="source-line-no">269</span><span id="line-269"> CONF.setLong(AbstractFSWAL.WAL_SYNC_TIMEOUT_MS, 10000);</span>
<span class="source-line-no">270</span><span id="line-270"> }</span>
<span class="source-line-no">271</span><span id="line-271"></span>
<span class="source-line-no">272</span><span id="line-272"> @After</span>
<span class="source-line-no">273</span><span id="line-273"> public void tearDown() throws IOException {</span>
<span class="source-line-no">274</span><span id="line-274"> // 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">275</span><span id="line-275"> HBaseTestingUtil.closeRegionAndWAL(region);</span>
<span class="source-line-no">276</span><span id="line-276"> EnvironmentEdgeManagerTestHelper.reset();</span>
<span class="source-line-no">277</span><span id="line-277"> LOG.info("Cleaning test directory: " + TEST_UTIL.getDataTestDir());</span>
<span class="source-line-no">278</span><span id="line-278"> TEST_UTIL.cleanupTestDir();</span>
<span class="source-line-no">279</span><span id="line-279"> }</span>
<span class="source-line-no">280</span><span id="line-280"></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 that I can use the max flushed sequence id after the close.</span>
<span class="source-line-no">283</span><span id="line-283"> */</span>
<span class="source-line-no">284</span><span id="line-284"> @Test</span>
<span class="source-line-no">285</span><span id="line-285"> public void testSequenceId() throws IOException {</span>
<span class="source-line-no">286</span><span id="line-286"> region = initHRegion(tableName, method, CONF, COLUMN_FAMILY_BYTES);</span>
<span class="source-line-no">287</span><span id="line-287"> assertEquals(HConstants.NO_SEQNUM, region.getMaxFlushedSeqId());</span>
<span class="source-line-no">288</span><span id="line-288"> // Weird. This returns 0 if no store files or no edits. Afraid to change it.</span>
<span class="source-line-no">289</span><span id="line-289"> assertEquals(0, (long) region.getMaxStoreSeqId().get(COLUMN_FAMILY_BYTES));</span>
<span class="source-line-no">290</span><span id="line-290"> HBaseTestingUtil.closeRegionAndWAL(this.region);</span>
<span class="source-line-no">291</span><span id="line-291"> assertEquals(HConstants.NO_SEQNUM, region.getMaxFlushedSeqId());</span>
<span class="source-line-no">292</span><span id="line-292"> assertEquals(0, (long) region.getMaxStoreSeqId().get(COLUMN_FAMILY_BYTES));</span>
<span class="source-line-no">293</span><span id="line-293"> HRegion oldRegion = region;</span>
<span class="source-line-no">294</span><span id="line-294"> try {</span>
<span class="source-line-no">295</span><span id="line-295"> // Open region again.</span>
<span class="source-line-no">296</span><span id="line-296"> region = initHRegion(tableName, method, CONF, COLUMN_FAMILY_BYTES);</span>
<span class="source-line-no">297</span><span id="line-297"> byte[] value = Bytes.toBytes(method);</span>
<span class="source-line-no">298</span><span id="line-298"> // Make a random put against our cf.</span>
<span class="source-line-no">299</span><span id="line-299"> Put put = new Put(value);</span>
<span class="source-line-no">300</span><span id="line-300"> put.addColumn(COLUMN_FAMILY_BYTES, null, value);</span>
<span class="source-line-no">301</span><span id="line-301"> region.put(put);</span>
<span class="source-line-no">302</span><span id="line-302"> // No flush yet so init numbers should still be in place.</span>
<span class="source-line-no">303</span><span id="line-303"> assertEquals(HConstants.NO_SEQNUM, region.getMaxFlushedSeqId());</span>
<span class="source-line-no">304</span><span id="line-304"> assertEquals(0, (long) region.getMaxStoreSeqId().get(COLUMN_FAMILY_BYTES));</span>
<span class="source-line-no">305</span><span id="line-305"> region.flush(true);</span>
<span class="source-line-no">306</span><span id="line-306"> long max = region.getMaxFlushedSeqId();</span>
<span class="source-line-no">307</span><span id="line-307"> HBaseTestingUtil.closeRegionAndWAL(this.region);</span>
<span class="source-line-no">308</span><span id="line-308"> assertEquals(max, region.getMaxFlushedSeqId());</span>
<span class="source-line-no">309</span><span id="line-309"> this.region = null;</span>
<span class="source-line-no">310</span><span id="line-310"> } finally {</span>
<span class="source-line-no">311</span><span id="line-311"> HBaseTestingUtil.closeRegionAndWAL(oldRegion);</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"></span>
<span class="source-line-no">315</span><span id="line-315"> /**</span>
<span class="source-line-no">316</span><span id="line-316"> * Test for Bug 2 of HBASE-10466. "Bug 2: Conditions for the first flush of region close</span>
<span class="source-line-no">317</span><span id="line-317"> * (so-called pre-flush) If memstoreSize is smaller than a certain value, or when region close</span>
<span class="source-line-no">318</span><span id="line-318"> * starts a flush is ongoing, the first flush is skipped and only the second flush takes place.</span>
<span class="source-line-no">319</span><span id="line-319"> * However, two flushes are required in case previous flush fails and leaves some data in</span>
<span class="source-line-no">320</span><span id="line-320"> * snapshot. The bug could cause loss of data in current memstore. The fix is removing all</span>
<span class="source-line-no">321</span><span id="line-321"> * conditions except abort check so we ensure 2 flushes for region close."</span>
<span class="source-line-no">322</span><span id="line-322"> */</span>
<span class="source-line-no">323</span><span id="line-323"> @Test</span>
<span class="source-line-no">324</span><span id="line-324"> public void testCloseCarryingSnapshot() throws IOException {</span>
<span class="source-line-no">325</span><span id="line-325"> region = initHRegion(tableName, method, CONF, COLUMN_FAMILY_BYTES);</span>
<span class="source-line-no">326</span><span id="line-326"> HStore store = region.getStore(COLUMN_FAMILY_BYTES);</span>
<span class="source-line-no">327</span><span id="line-327"> // Get some random bytes.</span>
<span class="source-line-no">328</span><span id="line-328"> byte[] value = Bytes.toBytes(method);</span>
<span class="source-line-no">329</span><span id="line-329"> // Make a random put against our cf.</span>
<span class="source-line-no">330</span><span id="line-330"> Put put = new Put(value);</span>
<span class="source-line-no">331</span><span id="line-331"> put.addColumn(COLUMN_FAMILY_BYTES, null, value);</span>
<span class="source-line-no">332</span><span id="line-332"> // First put something in current memstore, which will be in snapshot after flusher.prepare()</span>
<span class="source-line-no">333</span><span id="line-333"> region.put(put);</span>
<span class="source-line-no">334</span><span id="line-334"> StoreFlushContext storeFlushCtx = store.createFlushContext(12345, FlushLifeCycleTracker.DUMMY);</span>
<span class="source-line-no">335</span><span id="line-335"> storeFlushCtx.prepare();</span>
<span class="source-line-no">336</span><span id="line-336"> // Second put something in current memstore</span>
<span class="source-line-no">337</span><span id="line-337"> put.addColumn(COLUMN_FAMILY_BYTES, Bytes.toBytes("abc"), value);</span>
<span class="source-line-no">338</span><span id="line-338"> region.put(put);</span>
<span class="source-line-no">339</span><span id="line-339"> // Close with something in memstore and something in the snapshot. Make sure all is cleared.</span>
<span class="source-line-no">340</span><span id="line-340"> HBaseTestingUtil.closeRegionAndWAL(region);</span>
<span class="source-line-no">341</span><span id="line-341"> assertEquals(0, region.getMemStoreDataSize());</span>
<span class="source-line-no">342</span><span id="line-342"> region = null;</span>
<span class="source-line-no">343</span><span id="line-343"> }</span>
<span class="source-line-no">344</span><span id="line-344"></span>
<span class="source-line-no">345</span><span id="line-345"> /*</span>
<span class="source-line-no">346</span><span id="line-346"> * This test is for verifying memstore snapshot size is correctly updated in case of rollback See</span>
<span class="source-line-no">347</span><span id="line-347"> * HBASE-10845</span>
<span class="source-line-no">348</span><span id="line-348"> */</span>
<span class="source-line-no">349</span><span id="line-349"> @Test</span>
<span class="source-line-no">350</span><span id="line-350"> public void testMemstoreSnapshotSize() throws IOException {</span>
<span class="source-line-no">351</span><span id="line-351"> class MyFaultyFSLog extends FaultyFSLog {</span>
<span class="source-line-no">352</span><span id="line-352"> StoreFlushContext storeFlushCtx;</span>
<span class="source-line-no">353</span><span id="line-353"></span>
<span class="source-line-no">354</span><span id="line-354"> public MyFaultyFSLog(FileSystem fs, Path rootDir, String logName, Configuration conf)</span>
<span class="source-line-no">355</span><span id="line-355"> throws IOException {</span>
<span class="source-line-no">356</span><span id="line-356"> super(fs, rootDir, logName, conf);</span>
<span class="source-line-no">357</span><span id="line-357"> }</span>
<span class="source-line-no">358</span><span id="line-358"></span>
<span class="source-line-no">359</span><span id="line-359"> void setStoreFlushCtx(StoreFlushContext storeFlushCtx) {</span>
<span class="source-line-no">360</span><span id="line-360"> this.storeFlushCtx = storeFlushCtx;</span>
<span class="source-line-no">361</span><span id="line-361"> }</span>
<span class="source-line-no">362</span><span id="line-362"></span>
<span class="source-line-no">363</span><span id="line-363"> @Override</span>
<span class="source-line-no">364</span><span id="line-364"> protected void doSync(long txid, boolean forceSync) throws IOException {</span>
<span class="source-line-no">365</span><span id="line-365"> storeFlushCtx.prepare();</span>
<span class="source-line-no">366</span><span id="line-366"> super.doSync(txid, forceSync);</span>
<span class="source-line-no">367</span><span id="line-367"> }</span>
<span class="source-line-no">368</span><span id="line-368"> }</span>
<span class="source-line-no">369</span><span id="line-369"></span>
<span class="source-line-no">370</span><span id="line-370"> FileSystem fs = FileSystem.get(CONF);</span>
<span class="source-line-no">371</span><span id="line-371"> Path rootDir = new Path(dir + "testMemstoreSnapshotSize");</span>
<span class="source-line-no">372</span><span id="line-372"> MyFaultyFSLog faultyLog = new MyFaultyFSLog(fs, rootDir, "testMemstoreSnapshotSize", CONF);</span>
<span class="source-line-no">373</span><span id="line-373"> faultyLog.init();</span>
<span class="source-line-no">374</span><span id="line-374"> region = initHRegion(tableName, null, null, CONF, false, Durability.SYNC_WAL, faultyLog,</span>
<span class="source-line-no">375</span><span id="line-375"> COLUMN_FAMILY_BYTES);</span>
<span class="source-line-no">376</span><span id="line-376"></span>
<span class="source-line-no">377</span><span id="line-377"> HStore store = region.getStore(COLUMN_FAMILY_BYTES);</span>
<span class="source-line-no">378</span><span id="line-378"> // Get some random bytes.</span>
<span class="source-line-no">379</span><span id="line-379"> byte[] value = Bytes.toBytes(method);</span>
<span class="source-line-no">380</span><span id="line-380"> faultyLog.setStoreFlushCtx(store.createFlushContext(12345, FlushLifeCycleTracker.DUMMY));</span>
<span class="source-line-no">381</span><span id="line-381"></span>
<span class="source-line-no">382</span><span id="line-382"> Put put = new Put(value);</span>
<span class="source-line-no">383</span><span id="line-383"> put.addColumn(COLUMN_FAMILY_BYTES, Bytes.toBytes("abc"), value);</span>
<span class="source-line-no">384</span><span id="line-384"> faultyLog.setFailureType(FaultyFSLog.FailureType.SYNC);</span>
<span class="source-line-no">385</span><span id="line-385"> boolean threwIOE = false;</span>
<span class="source-line-no">386</span><span id="line-386"> try {</span>
<span class="source-line-no">387</span><span id="line-387"> region.put(put);</span>
<span class="source-line-no">388</span><span id="line-388"> } catch (IOException ioe) {</span>
<span class="source-line-no">389</span><span id="line-389"> threwIOE = true;</span>
<span class="source-line-no">390</span><span id="line-390"> } finally {</span>
<span class="source-line-no">391</span><span id="line-391"> assertTrue("The regionserver should have thrown an exception", threwIOE);</span>
<span class="source-line-no">392</span><span id="line-392"> }</span>
<span class="source-line-no">393</span><span id="line-393"> MemStoreSize mss = store.getFlushableSize();</span>
<span class="source-line-no">394</span><span id="line-394"> assertTrue("flushable size should be zero, but it is " + mss, mss.getDataSize() == 0);</span>
<span class="source-line-no">395</span><span id="line-395"> }</span>
<span class="source-line-no">396</span><span id="line-396"></span>
<span class="source-line-no">397</span><span id="line-397"> /**</span>
<span class="source-line-no">398</span><span id="line-398"> * Create a WAL outside of the usual helper in</span>
<span class="source-line-no">399</span><span id="line-399"> * {@link HBaseTestingUtil#createWal(Configuration, Path, RegionInfo)} because that method doesn't</span>
<span class="source-line-no">400</span><span id="line-400"> * play nicely with FaultyFileSystem. Call this method before overriding {@code fs.file.impl}.</span>
<span class="source-line-no">401</span><span id="line-401"> * @param callingMethod a unique component for the path, probably the name of the test method.</span>
<span class="source-line-no">402</span><span id="line-402"> */</span>
<span class="source-line-no">403</span><span id="line-403"> private static WAL createWALCompatibleWithFaultyFileSystem(String callingMethod,</span>
<span class="source-line-no">404</span><span id="line-404"> Configuration conf, TableName tableName) throws IOException {</span>
<span class="source-line-no">405</span><span id="line-405"> final Path logDir = TEST_UTIL.getDataTestDirOnTestFS(callingMethod + ".log");</span>
<span class="source-line-no">406</span><span id="line-406"> final Configuration walConf = new Configuration(conf);</span>
<span class="source-line-no">407</span><span id="line-407"> CommonFSUtils.setRootDir(walConf, logDir);</span>
<span class="source-line-no">408</span><span id="line-408"> return new WALFactory(walConf, callingMethod)</span>
<span class="source-line-no">409</span><span id="line-409"> .getWAL(RegionInfoBuilder.newBuilder(tableName).build());</span>
<span class="source-line-no">410</span><span id="line-410"> }</span>
<span class="source-line-no">411</span><span id="line-411"></span>
<span class="source-line-no">412</span><span id="line-412"> @Test</span>
<span class="source-line-no">413</span><span id="line-413"> public void testMemstoreSizeAccountingWithFailedPostBatchMutate() throws IOException {</span>
<span class="source-line-no">414</span><span id="line-414"> String testName = "testMemstoreSizeAccountingWithFailedPostBatchMutate";</span>
<span class="source-line-no">415</span><span id="line-415"> FileSystem fs = FileSystem.get(CONF);</span>
<span class="source-line-no">416</span><span id="line-416"> Path rootDir = new Path(dir + testName);</span>
<span class="source-line-no">417</span><span id="line-417"> FSHLog hLog = new FSHLog(fs, rootDir, testName, CONF);</span>
<span class="source-line-no">418</span><span id="line-418"> hLog.init();</span>
<span class="source-line-no">419</span><span id="line-419"> region = initHRegion(tableName, null, null, CONF, false, Durability.SYNC_WAL, hLog,</span>
<span class="source-line-no">420</span><span id="line-420"> COLUMN_FAMILY_BYTES);</span>
<span class="source-line-no">421</span><span id="line-421"> HStore store = region.getStore(COLUMN_FAMILY_BYTES);</span>
<span class="source-line-no">422</span><span id="line-422"> assertEquals(0, region.getMemStoreDataSize());</span>
<span class="source-line-no">423</span><span id="line-423"></span>
<span class="source-line-no">424</span><span id="line-424"> // Put one value</span>
<span class="source-line-no">425</span><span id="line-425"> byte[] value = Bytes.toBytes(method);</span>
<span class="source-line-no">426</span><span id="line-426"> Put put = new Put(value);</span>
<span class="source-line-no">427</span><span id="line-427"> put.addColumn(COLUMN_FAMILY_BYTES, Bytes.toBytes("abc"), value);</span>
<span class="source-line-no">428</span><span id="line-428"> region.put(put);</span>
<span class="source-line-no">429</span><span id="line-429"> long onePutSize = region.getMemStoreDataSize();</span>
<span class="source-line-no">430</span><span id="line-430"> assertTrue(onePutSize &gt; 0);</span>
<span class="source-line-no">431</span><span id="line-431"></span>
<span class="source-line-no">432</span><span id="line-432"> RegionCoprocessorHost mockedCPHost = mock(RegionCoprocessorHost.class);</span>
<span class="source-line-no">433</span><span id="line-433"> doThrow(new IOException()).when(mockedCPHost).postBatchMutate(any());</span>
<span class="source-line-no">434</span><span id="line-434"> region.setCoprocessorHost(mockedCPHost);</span>
<span class="source-line-no">435</span><span id="line-435"></span>
<span class="source-line-no">436</span><span id="line-436"> put = new Put(value);</span>
<span class="source-line-no">437</span><span id="line-437"> put.addColumn(COLUMN_FAMILY_BYTES, Bytes.toBytes("dfg"), value);</span>
<span class="source-line-no">438</span><span id="line-438"> try {</span>
<span class="source-line-no">439</span><span id="line-439"> region.put(put);</span>
<span class="source-line-no">440</span><span id="line-440"> fail("Should have failed with IOException");</span>
<span class="source-line-no">441</span><span id="line-441"> } catch (IOException expected) {</span>
<span class="source-line-no">442</span><span id="line-442"> }</span>
<span class="source-line-no">443</span><span id="line-443"> long expectedSize = onePutSize * 2;</span>
<span class="source-line-no">444</span><span id="line-444"> assertEquals("memstoreSize should be incremented", expectedSize, region.getMemStoreDataSize());</span>
<span class="source-line-no">445</span><span id="line-445"> assertEquals("flushable size should be incremented", expectedSize,</span>
<span class="source-line-no">446</span><span id="line-446"> store.getFlushableSize().getDataSize());</span>
<span class="source-line-no">447</span><span id="line-447"></span>
<span class="source-line-no">448</span><span id="line-448"> region.setCoprocessorHost(null);</span>
<span class="source-line-no">449</span><span id="line-449"> }</span>
<span class="source-line-no">450</span><span id="line-450"></span>
<span class="source-line-no">451</span><span id="line-451"> /**</span>
<span class="source-line-no">452</span><span id="line-452"> * A test case of HBASE-21041</span>
<span class="source-line-no">453</span><span id="line-453"> */</span>
<span class="source-line-no">454</span><span id="line-454"> @Test</span>
<span class="source-line-no">455</span><span id="line-455"> public void testFlushAndMemstoreSizeCounting() throws Exception {</span>
<span class="source-line-no">456</span><span id="line-456"> byte[] family = Bytes.toBytes("family");</span>
<span class="source-line-no">457</span><span id="line-457"> this.region = initHRegion(tableName, method, CONF, family);</span>
<span class="source-line-no">458</span><span id="line-458"> for (byte[] row : HBaseTestingUtil.ROWS) {</span>
<span class="source-line-no">459</span><span id="line-459"> Put put = new Put(row);</span>
<span class="source-line-no">460</span><span id="line-460"> put.addColumn(family, family, row);</span>
<span class="source-line-no">461</span><span id="line-461"> region.put(put);</span>
<span class="source-line-no">462</span><span id="line-462"> }</span>
<span class="source-line-no">463</span><span id="line-463"> region.flush(true);</span>
<span class="source-line-no">464</span><span id="line-464"> // After flush, data size should be zero</span>
<span class="source-line-no">465</span><span id="line-465"> assertEquals(0, region.getMemStoreDataSize());</span>
<span class="source-line-no">466</span><span id="line-466"> // After flush, a new active mutable segment is created, so the heap size</span>
<span class="source-line-no">467</span><span id="line-467"> // should equal to MutableSegment.DEEP_OVERHEAD</span>
<span class="source-line-no">468</span><span id="line-468"> assertEquals(MutableSegment.DEEP_OVERHEAD, region.getMemStoreHeapSize());</span>
<span class="source-line-no">469</span><span id="line-469"> // After flush, offheap should be zero</span>
<span class="source-line-no">470</span><span id="line-470"> assertEquals(0, region.getMemStoreOffHeapSize());</span>
<span class="source-line-no">471</span><span id="line-471"> }</span>
<span class="source-line-no">472</span><span id="line-472"></span>
<span class="source-line-no">473</span><span id="line-473"> /**</span>
<span class="source-line-no">474</span><span id="line-474"> * 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">475</span><span id="line-475"> * following from the issue description: "Bug 1: Wrong calculation of HRegion.memstoreSize: When a</span>
<span class="source-line-no">476</span><span id="line-476"> * flush fails, data to be flushed is kept in each MemStore's snapshot and wait for next flush</span>
<span class="source-line-no">477</span><span id="line-477"> * attempt to continue on it. But when the next flush succeeds, the counter of total memstore size</span>
<span class="source-line-no">478</span><span id="line-478"> * in HRegion is always deduced by the sum of current memstore sizes instead of snapshots left</span>
<span class="source-line-no">479</span><span id="line-479"> * from previous failed flush. This calculation is problematic that almost every time there is</span>
<span class="source-line-no">480</span><span id="line-480"> * failed flush, HRegion.memstoreSize gets reduced by a wrong value. If region flush could not</span>
<span class="source-line-no">481</span><span id="line-481"> * proceed for a couple cycles, the size in current memstore could be much larger than the</span>
<span class="source-line-no">482</span><span id="line-482"> * snapshot. It's likely to drift memstoreSize much smaller than expected. In extreme case, if the</span>
<span class="source-line-no">483</span><span id="line-483"> * error accumulates to even bigger than HRegion's memstore size limit, any further flush is</span>
<span class="source-line-no">484</span><span id="line-484"> * skipped because flush does not do anything if memstoreSize is not larger than 0."</span>
<span class="source-line-no">485</span><span id="line-485"> */</span>
<span class="source-line-no">486</span><span id="line-486"> @Test</span>
<span class="source-line-no">487</span><span id="line-487"> public void testFlushSizeAccounting() throws Exception {</span>
<span class="source-line-no">488</span><span id="line-488"> final Configuration conf = HBaseConfiguration.create(CONF);</span>
<span class="source-line-no">489</span><span id="line-489"> final WAL wal = createWALCompatibleWithFaultyFileSystem(method, conf, tableName);</span>
<span class="source-line-no">490</span><span id="line-490"> // Only retry once.</span>
<span class="source-line-no">491</span><span id="line-491"> conf.setInt("hbase.hstore.flush.retries.number", 1);</span>
<span class="source-line-no">492</span><span id="line-492"> final User user = User.createUserForTesting(conf, method, new String[] { "foo" });</span>
<span class="source-line-no">493</span><span id="line-493"> // Inject our faulty LocalFileSystem</span>
<span class="source-line-no">494</span><span id="line-494"> conf.setClass("fs.file.impl", FaultyFileSystem.class, FileSystem.class);</span>
<span class="source-line-no">495</span><span id="line-495"> user.runAs(new PrivilegedExceptionAction&lt;Object&gt;() {</span>
<span class="source-line-no">496</span><span id="line-496"> @Override</span>
<span class="source-line-no">497</span><span id="line-497"> public Object run() throws Exception {</span>
<span class="source-line-no">498</span><span id="line-498"> // Make sure it worked (above is sensitive to caching details in hadoop core)</span>
<span class="source-line-no">499</span><span id="line-499"> FileSystem fs = FileSystem.get(conf);</span>
<span class="source-line-no">500</span><span id="line-500"> Assert.assertEquals(FaultyFileSystem.class, fs.getClass());</span>
<span class="source-line-no">501</span><span id="line-501"> FaultyFileSystem ffs = (FaultyFileSystem) fs;</span>
<span class="source-line-no">502</span><span id="line-502"> HRegion region = null;</span>
<span class="source-line-no">503</span><span id="line-503"> try {</span>
<span class="source-line-no">504</span><span id="line-504"> // Initialize region</span>
<span class="source-line-no">505</span><span id="line-505"> region = initHRegion(tableName, null, null, CONF, false, Durability.SYNC_WAL, wal,</span>
<span class="source-line-no">506</span><span id="line-506"> COLUMN_FAMILY_BYTES);</span>
<span class="source-line-no">507</span><span id="line-507"> long size = region.getMemStoreDataSize();</span>
<span class="source-line-no">508</span><span id="line-508"> Assert.assertEquals(0, size);</span>
<span class="source-line-no">509</span><span id="line-509"> // Put one item into memstore. Measure the size of one item in memstore.</span>
<span class="source-line-no">510</span><span id="line-510"> Put p1 = new Put(row);</span>
<span class="source-line-no">511</span><span id="line-511"> p1.add(new KeyValue(row, COLUMN_FAMILY_BYTES, qual1, 1, (byte[]) null));</span>
<span class="source-line-no">512</span><span id="line-512"> region.put(p1);</span>
<span class="source-line-no">513</span><span id="line-513"> final long sizeOfOnePut = region.getMemStoreDataSize();</span>
<span class="source-line-no">514</span><span id="line-514"> // Fail a flush which means the current memstore will hang out as memstore 'snapshot'.</span>
<span class="source-line-no">515</span><span id="line-515"> try {</span>
<span class="source-line-no">516</span><span id="line-516"> LOG.info("Flushing");</span>
<span class="source-line-no">517</span><span id="line-517"> region.flush(true);</span>
<span class="source-line-no">518</span><span id="line-518"> Assert.fail("Didn't bubble up IOE!");</span>
<span class="source-line-no">519</span><span id="line-519"> } catch (DroppedSnapshotException dse) {</span>
<span class="source-line-no">520</span><span id="line-520"> // What we are expecting</span>
<span class="source-line-no">521</span><span id="line-521"> region.closing.set(false); // this is needed for the rest of the test to work</span>
<span class="source-line-no">522</span><span id="line-522"> }</span>
<span class="source-line-no">523</span><span id="line-523"> // Make it so all writes succeed from here on out</span>
<span class="source-line-no">524</span><span id="line-524"> ffs.fault.set(false);</span>
<span class="source-line-no">525</span><span id="line-525"> // Check sizes. Should still be the one entry.</span>
<span class="source-line-no">526</span><span id="line-526"> Assert.assertEquals(sizeOfOnePut, region.getMemStoreDataSize());</span>
<span class="source-line-no">527</span><span id="line-527"> // Now add two entries so that on this next flush that fails, we can see if we</span>
<span class="source-line-no">528</span><span id="line-528"> // subtract the right amount, the snapshot size only.</span>
<span class="source-line-no">529</span><span id="line-529"> Put p2 = new Put(row);</span>
<span class="source-line-no">530</span><span id="line-530"> p2.add(new KeyValue(row, COLUMN_FAMILY_BYTES, qual2, 2, (byte[]) null));</span>
<span class="source-line-no">531</span><span id="line-531"> p2.add(new KeyValue(row, COLUMN_FAMILY_BYTES, qual3, 3, (byte[]) null));</span>
<span class="source-line-no">532</span><span id="line-532"> region.put(p2);</span>
<span class="source-line-no">533</span><span id="line-533"> long expectedSize = sizeOfOnePut * 3;</span>
<span class="source-line-no">534</span><span id="line-534"> Assert.assertEquals(expectedSize, region.getMemStoreDataSize());</span>
<span class="source-line-no">535</span><span id="line-535"> // Do a successful flush. It will clear the snapshot only. Thats how flushes work.</span>
<span class="source-line-no">536</span><span id="line-536"> // If already a snapshot, we clear it else we move the memstore to be snapshot and flush</span>
<span class="source-line-no">537</span><span id="line-537"> // it</span>
<span class="source-line-no">538</span><span id="line-538"> region.flush(true);</span>
<span class="source-line-no">539</span><span id="line-539"> // Make sure our memory accounting is right.</span>
<span class="source-line-no">540</span><span id="line-540"> Assert.assertEquals(sizeOfOnePut * 2, region.getMemStoreDataSize());</span>
<span class="source-line-no">541</span><span id="line-541"> } finally {</span>
<span class="source-line-no">542</span><span id="line-542"> HBaseTestingUtil.closeRegionAndWAL(region);</span>
<span class="source-line-no">543</span><span id="line-543"> }</span>
<span class="source-line-no">544</span><span id="line-544"> return null;</span>
<span class="source-line-no">545</span><span id="line-545"> }</span>
<span class="source-line-no">546</span><span id="line-546"> });</span>
<span class="source-line-no">547</span><span id="line-547"> FileSystem.closeAllForUGI(user.getUGI());</span>
<span class="source-line-no">548</span><span id="line-548"> }</span>
<span class="source-line-no">549</span><span id="line-549"></span>
<span class="source-line-no">550</span><span id="line-550"> @Test</span>
<span class="source-line-no">551</span><span id="line-551"> public void testCloseWithFailingFlush() throws Exception {</span>
<span class="source-line-no">552</span><span id="line-552"> final Configuration conf = HBaseConfiguration.create(CONF);</span>
<span class="source-line-no">553</span><span id="line-553"> final WAL wal = createWALCompatibleWithFaultyFileSystem(method, conf, tableName);</span>
<span class="source-line-no">554</span><span id="line-554"> // Only retry once.</span>
<span class="source-line-no">555</span><span id="line-555"> conf.setInt("hbase.hstore.flush.retries.number", 1);</span>
<span class="source-line-no">556</span><span id="line-556"> final User user = User.createUserForTesting(conf, this.method, new String[] { "foo" });</span>
<span class="source-line-no">557</span><span id="line-557"> // Inject our faulty LocalFileSystem</span>
<span class="source-line-no">558</span><span id="line-558"> conf.setClass("fs.file.impl", FaultyFileSystem.class, FileSystem.class);</span>
<span class="source-line-no">559</span><span id="line-559"> user.runAs(new PrivilegedExceptionAction&lt;Object&gt;() {</span>
<span class="source-line-no">560</span><span id="line-560"> @Override</span>
<span class="source-line-no">561</span><span id="line-561"> public Object run() throws Exception {</span>
<span class="source-line-no">562</span><span id="line-562"> // Make sure it worked (above is sensitive to caching details in hadoop core)</span>
<span class="source-line-no">563</span><span id="line-563"> FileSystem fs = FileSystem.get(conf);</span>
<span class="source-line-no">564</span><span id="line-564"> Assert.assertEquals(FaultyFileSystem.class, fs.getClass());</span>
<span class="source-line-no">565</span><span id="line-565"> FaultyFileSystem ffs = (FaultyFileSystem) fs;</span>
<span class="source-line-no">566</span><span id="line-566"> HRegion region = null;</span>
<span class="source-line-no">567</span><span id="line-567"> try {</span>
<span class="source-line-no">568</span><span id="line-568"> // Initialize region</span>
<span class="source-line-no">569</span><span id="line-569"> region = initHRegion(tableName, null, null, CONF, false, Durability.SYNC_WAL, wal,</span>
<span class="source-line-no">570</span><span id="line-570"> COLUMN_FAMILY_BYTES);</span>
<span class="source-line-no">571</span><span id="line-571"> long size = region.getMemStoreDataSize();</span>
<span class="source-line-no">572</span><span id="line-572"> Assert.assertEquals(0, size);</span>
<span class="source-line-no">573</span><span id="line-573"> // Put one item into memstore. Measure the size of one item in memstore.</span>
<span class="source-line-no">574</span><span id="line-574"> Put p1 = new Put(row);</span>
<span class="source-line-no">575</span><span id="line-575"> p1.add(new KeyValue(row, COLUMN_FAMILY_BYTES, qual1, 1, (byte[]) null));</span>
<span class="source-line-no">576</span><span id="line-576"> region.put(p1);</span>
<span class="source-line-no">577</span><span id="line-577"> // Manufacture an outstanding snapshot -- fake a failed flush by doing prepare step only.</span>
<span class="source-line-no">578</span><span id="line-578"> HStore store = region.getStore(COLUMN_FAMILY_BYTES);</span>
<span class="source-line-no">579</span><span id="line-579"> StoreFlushContext storeFlushCtx =</span>
<span class="source-line-no">580</span><span id="line-580"> store.createFlushContext(12345, FlushLifeCycleTracker.DUMMY);</span>
<span class="source-line-no">581</span><span id="line-581"> storeFlushCtx.prepare();</span>
<span class="source-line-no">582</span><span id="line-582"> // Now add two entries to the foreground memstore.</span>
<span class="source-line-no">583</span><span id="line-583"> Put p2 = new Put(row);</span>
<span class="source-line-no">584</span><span id="line-584"> p2.add(new KeyValue(row, COLUMN_FAMILY_BYTES, qual2, 2, (byte[]) null));</span>
<span class="source-line-no">585</span><span id="line-585"> p2.add(new KeyValue(row, COLUMN_FAMILY_BYTES, qual3, 3, (byte[]) null));</span>
<span class="source-line-no">586</span><span id="line-586"> region.put(p2);</span>
<span class="source-line-no">587</span><span id="line-587"> // Now try close on top of a failing flush.</span>
<span class="source-line-no">588</span><span id="line-588"> HBaseTestingUtil.closeRegionAndWAL(region);</span>
<span class="source-line-no">589</span><span id="line-589"> region = null;</span>
<span class="source-line-no">590</span><span id="line-590"> fail();</span>
<span class="source-line-no">591</span><span id="line-591"> } catch (DroppedSnapshotException dse) {</span>
<span class="source-line-no">592</span><span id="line-592"> // Expected</span>
<span class="source-line-no">593</span><span id="line-593"> LOG.info("Expected DroppedSnapshotException");</span>
<span class="source-line-no">594</span><span id="line-594"> } finally {</span>
<span class="source-line-no">595</span><span id="line-595"> // Make it so all writes succeed from here on out so can close clean</span>
<span class="source-line-no">596</span><span id="line-596"> ffs.fault.set(false);</span>
<span class="source-line-no">597</span><span id="line-597"> HBaseTestingUtil.closeRegionAndWAL(region);</span>
<span class="source-line-no">598</span><span id="line-598"> }</span>
<span class="source-line-no">599</span><span id="line-599"> return null;</span>
<span class="source-line-no">600</span><span id="line-600"> }</span>
<span class="source-line-no">601</span><span id="line-601"> });</span>
<span class="source-line-no">602</span><span id="line-602"> FileSystem.closeAllForUGI(user.getUGI());</span>
<span class="source-line-no">603</span><span id="line-603"> }</span>
<span class="source-line-no">604</span><span id="line-604"></span>
<span class="source-line-no">605</span><span id="line-605"> @Test</span>
<span class="source-line-no">606</span><span id="line-606"> public void testCompactionAffectedByScanners() throws Exception {</span>
<span class="source-line-no">607</span><span id="line-607"> byte[] family = Bytes.toBytes("family");</span>
<span class="source-line-no">608</span><span id="line-608"> this.region = initHRegion(tableName, method, CONF, family);</span>
<span class="source-line-no">609</span><span id="line-609"></span>
<span class="source-line-no">610</span><span id="line-610"> Put put = new Put(Bytes.toBytes("r1"));</span>
<span class="source-line-no">611</span><span id="line-611"> put.addColumn(family, Bytes.toBytes("q1"), Bytes.toBytes("v1"));</span>
<span class="source-line-no">612</span><span id="line-612"> region.put(put);</span>
<span class="source-line-no">613</span><span id="line-613"> region.flush(true);</span>
<span class="source-line-no">614</span><span id="line-614"></span>
<span class="source-line-no">615</span><span id="line-615"> Scan scan = new Scan();</span>
<span class="source-line-no">616</span><span id="line-616"> scan.readVersions(3);</span>
<span class="source-line-no">617</span><span id="line-617"> // open the first scanner</span>
<span class="source-line-no">618</span><span id="line-618"> try (RegionScanner scanner1 = region.getScanner(scan)) {</span>
<span class="source-line-no">619</span><span id="line-619"> Delete delete = new Delete(Bytes.toBytes("r1"));</span>
<span class="source-line-no">620</span><span id="line-620"> region.delete(delete);</span>
<span class="source-line-no">621</span><span id="line-621"> region.flush(true);</span>
<span class="source-line-no">622</span><span id="line-622"> // open the second scanner</span>
<span class="source-line-no">623</span><span id="line-623"> try (RegionScanner scanner2 = region.getScanner(scan)) {</span>
<span class="source-line-no">624</span><span id="line-624"> List&lt;Cell&gt; results = new ArrayList&lt;&gt;();</span>
<span class="source-line-no">625</span><span id="line-625"></span>
<span class="source-line-no">626</span><span id="line-626"> LOG.info("Smallest read point:" + region.getSmallestReadPoint());</span>
<span class="source-line-no">627</span><span id="line-627"></span>
<span class="source-line-no">628</span><span id="line-628"> // make a major compaction</span>
<span class="source-line-no">629</span><span id="line-629"> region.compact(true);</span>
<span class="source-line-no">630</span><span id="line-630"></span>
<span class="source-line-no">631</span><span id="line-631"> // open the third scanner</span>
<span class="source-line-no">632</span><span id="line-632"> try (RegionScanner scanner3 = region.getScanner(scan)) {</span>
<span class="source-line-no">633</span><span id="line-633"> // get data from scanner 1, 2, 3 after major compaction</span>
<span class="source-line-no">634</span><span id="line-634"> scanner1.next(results);</span>
<span class="source-line-no">635</span><span id="line-635"> LOG.info(results.toString());</span>
<span class="source-line-no">636</span><span id="line-636"> assertEquals(1, results.size());</span>
<span class="source-line-no">637</span><span id="line-637"></span>
<span class="source-line-no">638</span><span id="line-638"> results.clear();</span>
<span class="source-line-no">639</span><span id="line-639"> scanner2.next(results);</span>
<span class="source-line-no">640</span><span id="line-640"> LOG.info(results.toString());</span>
<span class="source-line-no">641</span><span id="line-641"> assertEquals(0, results.size());</span>
<span class="source-line-no">642</span><span id="line-642"></span>
<span class="source-line-no">643</span><span id="line-643"> results.clear();</span>
<span class="source-line-no">644</span><span id="line-644"> scanner3.next(results);</span>
<span class="source-line-no">645</span><span id="line-645"> LOG.info(results.toString());</span>
<span class="source-line-no">646</span><span id="line-646"> assertEquals(0, results.size());</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"> }</span>
<span class="source-line-no">651</span><span id="line-651"></span>
<span class="source-line-no">652</span><span id="line-652"> @Test</span>
<span class="source-line-no">653</span><span id="line-653"> public void testToShowNPEOnRegionScannerReseek() throws Exception {</span>
<span class="source-line-no">654</span><span id="line-654"> byte[] family = Bytes.toBytes("family");</span>
<span class="source-line-no">655</span><span id="line-655"> this.region = initHRegion(tableName, method, CONF, family);</span>
<span class="source-line-no">656</span><span id="line-656"></span>
<span class="source-line-no">657</span><span id="line-657"> Put put = new Put(Bytes.toBytes("r1"));</span>
<span class="source-line-no">658</span><span id="line-658"> put.addColumn(family, Bytes.toBytes("q1"), Bytes.toBytes("v1"));</span>
<span class="source-line-no">659</span><span id="line-659"> region.put(put);</span>
<span class="source-line-no">660</span><span id="line-660"> put = new Put(Bytes.toBytes("r2"));</span>
<span class="source-line-no">661</span><span id="line-661"> put.addColumn(family, Bytes.toBytes("q1"), Bytes.toBytes("v1"));</span>
<span class="source-line-no">662</span><span id="line-662"> region.put(put);</span>
<span class="source-line-no">663</span><span id="line-663"> region.flush(true);</span>
<span class="source-line-no">664</span><span id="line-664"></span>
<span class="source-line-no">665</span><span id="line-665"> Scan scan = new Scan();</span>
<span class="source-line-no">666</span><span id="line-666"> scan.readVersions(3);</span>
<span class="source-line-no">667</span><span id="line-667"> // open the first scanner</span>
<span class="source-line-no">668</span><span id="line-668"> try (RegionScanner scanner1 = region.getScanner(scan)) {</span>
<span class="source-line-no">669</span><span id="line-669"> LOG.info("Smallest read point:" + region.getSmallestReadPoint());</span>
<span class="source-line-no">670</span><span id="line-670"></span>
<span class="source-line-no">671</span><span id="line-671"> region.compact(true);</span>
<span class="source-line-no">672</span><span id="line-672"></span>
<span class="source-line-no">673</span><span id="line-673"> scanner1.reseek(Bytes.toBytes("r2"));</span>
<span class="source-line-no">674</span><span id="line-674"> List&lt;Cell&gt; results = new ArrayList&lt;&gt;();</span>
<span class="source-line-no">675</span><span id="line-675"> scanner1.next(results);</span>
<span class="source-line-no">676</span><span id="line-676"> Cell keyValue = results.get(0);</span>
<span class="source-line-no">677</span><span id="line-677"> assertTrue(Bytes.compareTo(CellUtil.cloneRow(keyValue), Bytes.toBytes("r2")) == 0);</span>
<span class="source-line-no">678</span><span id="line-678"> scanner1.close();</span>
<span class="source-line-no">679</span><span id="line-679"> }</span>
<span class="source-line-no">680</span><span id="line-680"> }</span>
<span class="source-line-no">681</span><span id="line-681"></span>
<span class="source-line-no">682</span><span id="line-682"> @Test</span>
<span class="source-line-no">683</span><span id="line-683"> public void testArchiveRecoveredEditsReplay() throws Exception {</span>
<span class="source-line-no">684</span><span id="line-684"> byte[] family = Bytes.toBytes("family");</span>
<span class="source-line-no">685</span><span id="line-685"> this.region = initHRegion(tableName, method, CONF, family);</span>
<span class="source-line-no">686</span><span id="line-686"> final WALFactory wals = new WALFactory(CONF, method);</span>
<span class="source-line-no">687</span><span id="line-687"> try {</span>
<span class="source-line-no">688</span><span id="line-688"> Path regiondir = region.getRegionFileSystem().getRegionDir();</span>
<span class="source-line-no">689</span><span id="line-689"> FileSystem fs = region.getRegionFileSystem().getFileSystem();</span>
<span class="source-line-no">690</span><span id="line-690"> byte[] regionName = region.getRegionInfo().getEncodedNameAsBytes();</span>
<span class="source-line-no">691</span><span id="line-691"></span>
<span class="source-line-no">692</span><span id="line-692"> Path recoveredEditsDir = WALSplitUtil.getRegionDirRecoveredEditsDir(regiondir);</span>
<span class="source-line-no">693</span><span id="line-693"></span>
<span class="source-line-no">694</span><span id="line-694"> long maxSeqId = 1050;</span>
<span class="source-line-no">695</span><span id="line-695"> long minSeqId = 1000;</span>
<span class="source-line-no">696</span><span id="line-696"></span>
<span class="source-line-no">697</span><span id="line-697"> for (long i = minSeqId; i &lt;= maxSeqId; i += 10) {</span>
<span class="source-line-no">698</span><span id="line-698"> Path recoveredEdits = new Path(recoveredEditsDir, String.format("%019d", i));</span>
<span class="source-line-no">699</span><span id="line-699"> fs.create(recoveredEdits);</span>
<span class="source-line-no">700</span><span id="line-700"> WALProvider.Writer writer = wals.createRecoveredEditsWriter(fs, recoveredEdits);</span>
<span class="source-line-no">701</span><span id="line-701"></span>
<span class="source-line-no">702</span><span id="line-702"> long time = System.nanoTime();</span>
<span class="source-line-no">703</span><span id="line-703"> WALEdit edit = new WALEdit();</span>
<span class="source-line-no">704</span><span id="line-704"> WALEditInternalHelper.addExtendedCell(edit,</span>
<span class="source-line-no">705</span><span id="line-705"> new KeyValue(row, family, Bytes.toBytes(i), time, KeyValue.Type.Put, Bytes.toBytes(i)));</span>
<span class="source-line-no">706</span><span id="line-706"> writer.append(new WAL.Entry(</span>
<span class="source-line-no">707</span><span id="line-707"> new WALKeyImpl(regionName, tableName, i, time, HConstants.DEFAULT_CLUSTER_ID), edit));</span>
<span class="source-line-no">708</span><span id="line-708"></span>
<span class="source-line-no">709</span><span id="line-709"> writer.close();</span>
<span class="source-line-no">710</span><span id="line-710"> }</span>
<span class="source-line-no">711</span><span id="line-711"> MonitoredTask status = TaskMonitor.get().createStatus(method);</span>
<span class="source-line-no">712</span><span id="line-712"> Map&lt;byte[], Long&gt; maxSeqIdInStores = new TreeMap&lt;&gt;(Bytes.BYTES_COMPARATOR);</span>
<span class="source-line-no">713</span><span id="line-713"> for (HStore store : region.getStores()) {</span>
<span class="source-line-no">714</span><span id="line-714"> maxSeqIdInStores.put(Bytes.toBytes(store.getColumnFamilyName()), minSeqId - 1);</span>
<span class="source-line-no">715</span><span id="line-715"> }</span>
<span class="source-line-no">716</span><span id="line-716"> CONF.set("hbase.region.archive.recovered.edits", "true");</span>
<span class="source-line-no">717</span><span id="line-717"> CONF.set(CommonFSUtils.HBASE_WAL_DIR, "/custom_wal_dir");</span>
<span class="source-line-no">718</span><span id="line-718"> long seqId = region.replayRecoveredEditsIfAny(maxSeqIdInStores, null, status);</span>
<span class="source-line-no">719</span><span id="line-719"> assertEquals(maxSeqId, seqId);</span>
<span class="source-line-no">720</span><span id="line-720"> region.getMVCC().advanceTo(seqId);</span>
<span class="source-line-no">721</span><span id="line-721"> String fakeFamilyName = recoveredEditsDir.getName();</span>
<span class="source-line-no">722</span><span id="line-722"> Path rootDir = new Path(CONF.get(HConstants.HBASE_DIR));</span>
<span class="source-line-no">723</span><span id="line-723"> Path storeArchiveDir = HFileArchiveUtil.getStoreArchivePathForRootDir(rootDir,</span>
<span class="source-line-no">724</span><span id="line-724"> region.getRegionInfo(), Bytes.toBytes(fakeFamilyName));</span>
<span class="source-line-no">725</span><span id="line-725"> FileStatus[] list = TEST_UTIL.getTestFileSystem().listStatus(storeArchiveDir);</span>
<span class="source-line-no">726</span><span id="line-726"> assertEquals(6, list.length);</span>
<span class="source-line-no">727</span><span id="line-727"> } finally {</span>
<span class="source-line-no">728</span><span id="line-728"> CONF.set("hbase.region.archive.recovered.edits", "false");</span>
<span class="source-line-no">729</span><span id="line-729"> CONF.set(CommonFSUtils.HBASE_WAL_DIR, "");</span>
<span class="source-line-no">730</span><span id="line-730"> HBaseTestingUtil.closeRegionAndWAL(this.region);</span>
<span class="source-line-no">731</span><span id="line-731"> this.region = null;</span>
<span class="source-line-no">732</span><span id="line-732"> wals.close();</span>
<span class="source-line-no">733</span><span id="line-733"> }</span>
<span class="source-line-no">734</span><span id="line-734"> }</span>
<span class="source-line-no">735</span><span id="line-735"></span>
<span class="source-line-no">736</span><span id="line-736"> @Test</span>
<span class="source-line-no">737</span><span id="line-737"> public void testSkipRecoveredEditsReplay() throws Exception {</span>
<span class="source-line-no">738</span><span id="line-738"> byte[] family = Bytes.toBytes("family");</span>
<span class="source-line-no">739</span><span id="line-739"> this.region = initHRegion(tableName, method, CONF, family);</span>
<span class="source-line-no">740</span><span id="line-740"> final WALFactory wals = new WALFactory(CONF, method);</span>
<span class="source-line-no">741</span><span id="line-741"> try {</span>
<span class="source-line-no">742</span><span id="line-742"> Path regiondir = region.getRegionFileSystem().getRegionDir();</span>
<span class="source-line-no">743</span><span id="line-743"> FileSystem fs = region.getRegionFileSystem().getFileSystem();</span>
<span class="source-line-no">744</span><span id="line-744"> byte[] regionName = region.getRegionInfo().getEncodedNameAsBytes();</span>
<span class="source-line-no">745</span><span id="line-745"></span>
<span class="source-line-no">746</span><span id="line-746"> Path recoveredEditsDir = WALSplitUtil.getRegionDirRecoveredEditsDir(regiondir);</span>
<span class="source-line-no">747</span><span id="line-747"></span>
<span class="source-line-no">748</span><span id="line-748"> long maxSeqId = 1050;</span>
<span class="source-line-no">749</span><span id="line-749"> long minSeqId = 1000;</span>
<span class="source-line-no">750</span><span id="line-750"></span>
<span class="source-line-no">751</span><span id="line-751"> for (long i = minSeqId; i &lt;= maxSeqId; i += 10) {</span>
<span class="source-line-no">752</span><span id="line-752"> Path recoveredEdits = new Path(recoveredEditsDir, String.format("%019d", i));</span>
<span class="source-line-no">753</span><span id="line-753"> fs.create(recoveredEdits);</span>
<span class="source-line-no">754</span><span id="line-754"> WALProvider.Writer writer = wals.createRecoveredEditsWriter(fs, recoveredEdits);</span>
<span class="source-line-no">755</span><span id="line-755"></span>
<span class="source-line-no">756</span><span id="line-756"> long time = System.nanoTime();</span>
<span class="source-line-no">757</span><span id="line-757"> WALEdit edit = new WALEdit();</span>
<span class="source-line-no">758</span><span id="line-758"> WALEditInternalHelper.addExtendedCell(edit,</span>
<span class="source-line-no">759</span><span id="line-759"> new KeyValue(row, family, Bytes.toBytes(i), time, KeyValue.Type.Put, Bytes.toBytes(i)));</span>
<span class="source-line-no">760</span><span id="line-760"> writer.append(new WAL.Entry(</span>
<span class="source-line-no">761</span><span id="line-761"> new WALKeyImpl(regionName, tableName, i, time, HConstants.DEFAULT_CLUSTER_ID), edit));</span>
<span class="source-line-no">762</span><span id="line-762"></span>
<span class="source-line-no">763</span><span id="line-763"> writer.close();</span>
<span class="source-line-no">764</span><span id="line-764"> }</span>
<span class="source-line-no">765</span><span id="line-765"> MonitoredTask status = TaskMonitor.get().createStatus(method);</span>
<span class="source-line-no">766</span><span id="line-766"> Map&lt;byte[], Long&gt; maxSeqIdInStores = new TreeMap&lt;&gt;(Bytes.BYTES_COMPARATOR);</span>
<span class="source-line-no">767</span><span id="line-767"> for (HStore store : region.getStores()) {</span>
<span class="source-line-no">768</span><span id="line-768"> maxSeqIdInStores.put(Bytes.toBytes(store.getColumnFamilyName()), minSeqId - 1);</span>
<span class="source-line-no">769</span><span id="line-769"> }</span>
<span class="source-line-no">770</span><span id="line-770"> long seqId = region.replayRecoveredEditsIfAny(maxSeqIdInStores, null, status);</span>
<span class="source-line-no">771</span><span id="line-771"> assertEquals(maxSeqId, seqId);</span>
<span class="source-line-no">772</span><span id="line-772"> region.getMVCC().advanceTo(seqId);</span>
<span class="source-line-no">773</span><span id="line-773"> Get get = new Get(row);</span>
<span class="source-line-no">774</span><span id="line-774"> Result result = region.get(get);</span>
<span class="source-line-no">775</span><span id="line-775"> for (long i = minSeqId; i &lt;= maxSeqId; i += 10) {</span>
<span class="source-line-no">776</span><span id="line-776"> List&lt;Cell&gt; kvs = result.getColumnCells(family, Bytes.toBytes(i));</span>
<span class="source-line-no">777</span><span id="line-777"> assertEquals(1, kvs.size());</span>
<span class="source-line-no">778</span><span id="line-778"> assertArrayEquals(Bytes.toBytes(i), CellUtil.cloneValue(kvs.get(0)));</span>
<span class="source-line-no">779</span><span id="line-779"> }</span>
<span class="source-line-no">780</span><span id="line-780"> } finally {</span>
<span class="source-line-no">781</span><span id="line-781"> HBaseTestingUtil.closeRegionAndWAL(this.region);</span>
<span class="source-line-no">782</span><span id="line-782"> this.region = null;</span>
<span class="source-line-no">783</span><span id="line-783"> wals.close();</span>
<span class="source-line-no">784</span><span id="line-784"> }</span>
<span class="source-line-no">785</span><span id="line-785"> }</span>
<span class="source-line-no">786</span><span id="line-786"></span>
<span class="source-line-no">787</span><span id="line-787"> @Test</span>
<span class="source-line-no">788</span><span id="line-788"> public void testSkipRecoveredEditsReplaySomeIgnored() throws Exception {</span>
<span class="source-line-no">789</span><span id="line-789"> byte[] family = Bytes.toBytes("family");</span>
<span class="source-line-no">790</span><span id="line-790"> this.region = initHRegion(tableName, method, CONF, family);</span>
<span class="source-line-no">791</span><span id="line-791"> final WALFactory wals = new WALFactory(CONF, method);</span>
<span class="source-line-no">792</span><span id="line-792"> try {</span>
<span class="source-line-no">793</span><span id="line-793"> Path regiondir = region.getRegionFileSystem().getRegionDir();</span>
<span class="source-line-no">794</span><span id="line-794"> FileSystem fs = region.getRegionFileSystem().getFileSystem();</span>
<span class="source-line-no">795</span><span id="line-795"> byte[] regionName = region.getRegionInfo().getEncodedNameAsBytes();</span>
<span class="source-line-no">796</span><span id="line-796"></span>
<span class="source-line-no">797</span><span id="line-797"> Path recoveredEditsDir = WALSplitUtil.getRegionDirRecoveredEditsDir(regiondir);</span>
<span class="source-line-no">798</span><span id="line-798"></span>
<span class="source-line-no">799</span><span id="line-799"> long maxSeqId = 1050;</span>
<span class="source-line-no">800</span><span id="line-800"> long minSeqId = 1000;</span>
<span class="source-line-no">801</span><span id="line-801"></span>
<span class="source-line-no">802</span><span id="line-802"> for (long i = minSeqId; i &lt;= maxSeqId; i += 10) {</span>
<span class="source-line-no">803</span><span id="line-803"> Path recoveredEdits = new Path(recoveredEditsDir, String.format("%019d", i));</span>
<span class="source-line-no">804</span><span id="line-804"> fs.create(recoveredEdits);</span>
<span class="source-line-no">805</span><span id="line-805"> WALProvider.Writer writer = wals.createRecoveredEditsWriter(fs, recoveredEdits);</span>
<span class="source-line-no">806</span><span id="line-806"></span>
<span class="source-line-no">807</span><span id="line-807"> long time = System.nanoTime();</span>
<span class="source-line-no">808</span><span id="line-808"> WALEdit edit = new WALEdit();</span>
<span class="source-line-no">809</span><span id="line-809"> WALEditInternalHelper.addExtendedCell(edit,</span>
<span class="source-line-no">810</span><span id="line-810"> new KeyValue(row, family, Bytes.toBytes(i), time, KeyValue.Type.Put, Bytes.toBytes(i)));</span>
<span class="source-line-no">811</span><span id="line-811"> writer.append(new WAL.Entry(</span>
<span class="source-line-no">812</span><span id="line-812"> new WALKeyImpl(regionName, tableName, i, time, HConstants.DEFAULT_CLUSTER_ID), edit));</span>
<span class="source-line-no">813</span><span id="line-813"></span>
<span class="source-line-no">814</span><span id="line-814"> writer.close();</span>
<span class="source-line-no">815</span><span id="line-815"> }</span>
<span class="source-line-no">816</span><span id="line-816"> long recoverSeqId = 1030;</span>
<span class="source-line-no">817</span><span id="line-817"> MonitoredTask status = TaskMonitor.get().createStatus(method);</span>
<span class="source-line-no">818</span><span id="line-818"> Map&lt;byte[], Long&gt; maxSeqIdInStores = new TreeMap&lt;&gt;(Bytes.BYTES_COMPARATOR);</span>
<span class="source-line-no">819</span><span id="line-819"> for (HStore store : region.getStores()) {</span>
<span class="source-line-no">820</span><span id="line-820"> maxSeqIdInStores.put(Bytes.toBytes(store.getColumnFamilyName()), recoverSeqId - 1);</span>
<span class="source-line-no">821</span><span id="line-821"> }</span>
<span class="source-line-no">822</span><span id="line-822"> long seqId = region.replayRecoveredEditsIfAny(maxSeqIdInStores, null, status);</span>
<span class="source-line-no">823</span><span id="line-823"> assertEquals(maxSeqId, seqId);</span>
<span class="source-line-no">824</span><span id="line-824"> region.getMVCC().advanceTo(seqId);</span>
<span class="source-line-no">825</span><span id="line-825"> Get get = new Get(row);</span>
<span class="source-line-no">826</span><span id="line-826"> Result result = region.get(get);</span>
<span class="source-line-no">827</span><span id="line-827"> for (long i = minSeqId; i &lt;= maxSeqId; i += 10) {</span>
<span class="source-line-no">828</span><span id="line-828"> List&lt;Cell&gt; kvs = result.getColumnCells(family, Bytes.toBytes(i));</span>
<span class="source-line-no">829</span><span id="line-829"> if (i &lt; recoverSeqId) {</span>
<span class="source-line-no">830</span><span id="line-830"> assertEquals(0, kvs.size());</span>
<span class="source-line-no">831</span><span id="line-831"> } else {</span>
<span class="source-line-no">832</span><span id="line-832"> assertEquals(1, kvs.size());</span>
<span class="source-line-no">833</span><span id="line-833"> assertArrayEquals(Bytes.toBytes(i), CellUtil.cloneValue(kvs.get(0)));</span>
<span class="source-line-no">834</span><span id="line-834"> }</span>
<span class="source-line-no">835</span><span id="line-835"> }</span>
<span class="source-line-no">836</span><span id="line-836"> } finally {</span>
<span class="source-line-no">837</span><span id="line-837"> HBaseTestingUtil.closeRegionAndWAL(this.region);</span>
<span class="source-line-no">838</span><span id="line-838"> this.region = null;</span>
<span class="source-line-no">839</span><span id="line-839"> wals.close();</span>
<span class="source-line-no">840</span><span id="line-840"> }</span>
<span class="source-line-no">841</span><span id="line-841"> }</span>
<span class="source-line-no">842</span><span id="line-842"></span>
<span class="source-line-no">843</span><span id="line-843"> @Test</span>
<span class="source-line-no">844</span><span id="line-844"> public void testSkipRecoveredEditsReplayAllIgnored() throws Exception {</span>
<span class="source-line-no">845</span><span id="line-845"> byte[] family = Bytes.toBytes("family");</span>
<span class="source-line-no">846</span><span id="line-846"> this.region = initHRegion(tableName, method, CONF, family);</span>
<span class="source-line-no">847</span><span id="line-847"> Path regiondir = region.getRegionFileSystem().getRegionDir();</span>
<span class="source-line-no">848</span><span id="line-848"> FileSystem fs = region.getRegionFileSystem().getFileSystem();</span>
<span class="source-line-no">849</span><span id="line-849"></span>
<span class="source-line-no">850</span><span id="line-850"> Path recoveredEditsDir = WALSplitUtil.getRegionDirRecoveredEditsDir(regiondir);</span>
<span class="source-line-no">851</span><span id="line-851"> for (int i = 1000; i &lt; 1050; i += 10) {</span>
<span class="source-line-no">852</span><span id="line-852"> Path recoveredEdits = new Path(recoveredEditsDir, String.format("%019d", i));</span>
<span class="source-line-no">853</span><span id="line-853"> FSDataOutputStream dos = fs.create(recoveredEdits);</span>
<span class="source-line-no">854</span><span id="line-854"> dos.writeInt(i);</span>
<span class="source-line-no">855</span><span id="line-855"> dos.close();</span>
<span class="source-line-no">856</span><span id="line-856"> }</span>
<span class="source-line-no">857</span><span id="line-857"> long minSeqId = 2000;</span>
<span class="source-line-no">858</span><span id="line-858"> Path recoveredEdits = new Path(recoveredEditsDir, String.format("%019d", minSeqId - 1));</span>
<span class="source-line-no">859</span><span id="line-859"> FSDataOutputStream dos = fs.create(recoveredEdits);</span>
<span class="source-line-no">860</span><span id="line-860"> dos.close();</span>
<span class="source-line-no">861</span><span id="line-861"></span>
<span class="source-line-no">862</span><span id="line-862"> Map&lt;byte[], Long&gt; maxSeqIdInStores = new TreeMap&lt;&gt;(Bytes.BYTES_COMPARATOR);</span>
<span class="source-line-no">863</span><span id="line-863"> for (HStore store : region.getStores()) {</span>
<span class="source-line-no">864</span><span id="line-864"> maxSeqIdInStores.put(Bytes.toBytes(store.getColumnFamilyName()), minSeqId);</span>
<span class="source-line-no">865</span><span id="line-865"> }</span>
<span class="source-line-no">866</span><span id="line-866"> long seqId = region.replayRecoveredEditsIfAny(maxSeqIdInStores, null, null);</span>
<span class="source-line-no">867</span><span id="line-867"> assertEquals(minSeqId, seqId);</span>
<span class="source-line-no">868</span><span id="line-868"> }</span>
<span class="source-line-no">869</span><span id="line-869"></span>
<span class="source-line-no">870</span><span id="line-870"> @Test</span>
<span class="source-line-no">871</span><span id="line-871"> public void testSkipRecoveredEditsReplayTheLastFileIgnored() throws Exception {</span>
<span class="source-line-no">872</span><span id="line-872"> byte[] family = Bytes.toBytes("family");</span>
<span class="source-line-no">873</span><span id="line-873"> this.region = initHRegion(tableName, method, CONF, family);</span>
<span class="source-line-no">874</span><span id="line-874"> final WALFactory wals = new WALFactory(CONF, method);</span>
<span class="source-line-no">875</span><span id="line-875"> try {</span>
<span class="source-line-no">876</span><span id="line-876"> Path regiondir = region.getRegionFileSystem().getRegionDir();</span>
<span class="source-line-no">877</span><span id="line-877"> FileSystem fs = region.getRegionFileSystem().getFileSystem();</span>
<span class="source-line-no">878</span><span id="line-878"> byte[] regionName = region.getRegionInfo().getEncodedNameAsBytes();</span>
<span class="source-line-no">879</span><span id="line-879"> byte[][] columns = region.getTableDescriptor().getColumnFamilyNames().toArray(new byte[0][]);</span>
<span class="source-line-no">880</span><span id="line-880"></span>
<span class="source-line-no">881</span><span id="line-881"> assertEquals(0, region.getStoreFileList(columns).size());</span>
<span class="source-line-no">882</span><span id="line-882"></span>
<span class="source-line-no">883</span><span id="line-883"> Path recoveredEditsDir = WALSplitUtil.getRegionDirRecoveredEditsDir(regiondir);</span>
<span class="source-line-no">884</span><span id="line-884"></span>
<span class="source-line-no">885</span><span id="line-885"> long maxSeqId = 1050;</span>
<span class="source-line-no">886</span><span id="line-886"> long minSeqId = 1000;</span>
<span class="source-line-no">887</span><span id="line-887"></span>
<span class="source-line-no">888</span><span id="line-888"> for (long i = minSeqId; i &lt;= maxSeqId; i += 10) {</span>
<span class="source-line-no">889</span><span id="line-889"> Path recoveredEdits = new Path(recoveredEditsDir, String.format("%019d", i));</span>
<span class="source-line-no">890</span><span id="line-890"> fs.create(recoveredEdits);</span>
<span class="source-line-no">891</span><span id="line-891"> WALProvider.Writer writer = wals.createRecoveredEditsWriter(fs, recoveredEdits);</span>
<span class="source-line-no">892</span><span id="line-892"></span>
<span class="source-line-no">893</span><span id="line-893"> long time = System.nanoTime();</span>
<span class="source-line-no">894</span><span id="line-894"> WALEdit edit = null;</span>
<span class="source-line-no">895</span><span id="line-895"> if (i == maxSeqId) {</span>
<span class="source-line-no">896</span><span id="line-896"> edit = WALEdit.createCompaction(region.getRegionInfo(),</span>
<span class="source-line-no">897</span><span id="line-897"> CompactionDescriptor.newBuilder().setTableName(ByteString.copyFrom(tableName.getName()))</span>
<span class="source-line-no">898</span><span id="line-898"> .setFamilyName(ByteString.copyFrom(regionName))</span>
<span class="source-line-no">899</span><span id="line-899"> .setEncodedRegionName(ByteString.copyFrom(regionName))</span>
<span class="source-line-no">900</span><span id="line-900"> .setStoreHomeDirBytes(ByteString.copyFrom(Bytes.toBytes(regiondir.toString())))</span>
<span class="source-line-no">901</span><span id="line-901"> .setRegionName(ByteString.copyFrom(region.getRegionInfo().getRegionName())).build());</span>
<span class="source-line-no">902</span><span id="line-902"> } else {</span>
<span class="source-line-no">903</span><span id="line-903"> edit = new WALEdit();</span>
<span class="source-line-no">904</span><span id="line-904"> WALEditInternalHelper.addExtendedCell(edit,</span>
<span class="source-line-no">905</span><span id="line-905"> new KeyValue(row, family, Bytes.toBytes(i), time, KeyValue.Type.Put, Bytes.toBytes(i)));</span>
<span class="source-line-no">906</span><span id="line-906"> }</span>
<span class="source-line-no">907</span><span id="line-907"> writer.append(new WAL.Entry(</span>
<span class="source-line-no">908</span><span id="line-908"> new WALKeyImpl(regionName, tableName, i, time, HConstants.DEFAULT_CLUSTER_ID), edit));</span>
<span class="source-line-no">909</span><span id="line-909"> writer.close();</span>
<span class="source-line-no">910</span><span id="line-910"> }</span>
<span class="source-line-no">911</span><span id="line-911"></span>
<span class="source-line-no">912</span><span id="line-912"> long recoverSeqId = 1030;</span>
<span class="source-line-no">913</span><span id="line-913"> Map&lt;byte[], Long&gt; maxSeqIdInStores = new TreeMap&lt;&gt;(Bytes.BYTES_COMPARATOR);</span>
<span class="source-line-no">914</span><span id="line-914"> MonitoredTask status = TaskMonitor.get().createStatus(method);</span>
<span class="source-line-no">915</span><span id="line-915"> for (HStore store : region.getStores()) {</span>
<span class="source-line-no">916</span><span id="line-916"> maxSeqIdInStores.put(Bytes.toBytes(store.getColumnFamilyName()), recoverSeqId - 1);</span>
<span class="source-line-no">917</span><span id="line-917"> }</span>
<span class="source-line-no">918</span><span id="line-918"> long seqId = region.replayRecoveredEditsIfAny(maxSeqIdInStores, null, status);</span>
<span class="source-line-no">919</span><span id="line-919"> assertEquals(maxSeqId, seqId);</span>
<span class="source-line-no">920</span><span id="line-920"></span>
<span class="source-line-no">921</span><span id="line-921"> // assert that the files are flushed</span>
<span class="source-line-no">922</span><span id="line-922"> assertEquals(1, region.getStoreFileList(columns).size());</span>
<span class="source-line-no">923</span><span id="line-923"></span>
<span class="source-line-no">924</span><span id="line-924"> } finally {</span>
<span class="source-line-no">925</span><span id="line-925"> HBaseTestingUtil.closeRegionAndWAL(this.region);</span>
<span class="source-line-no">926</span><span id="line-926"> this.region = null;</span>
<span class="source-line-no">927</span><span id="line-927"> wals.close();</span>
<span class="source-line-no">928</span><span id="line-928"> }</span>
<span class="source-line-no">929</span><span id="line-929"> }</span>
<span class="source-line-no">930</span><span id="line-930"></span>
<span class="source-line-no">931</span><span id="line-931"> @Test</span>
<span class="source-line-no">932</span><span id="line-932"> public void testRecoveredEditsReplayCompaction() throws Exception {</span>
<span class="source-line-no">933</span><span id="line-933"> testRecoveredEditsReplayCompaction(false);</span>
<span class="source-line-no">934</span><span id="line-934"> testRecoveredEditsReplayCompaction(true);</span>
<span class="source-line-no">935</span><span id="line-935"> }</span>
<span class="source-line-no">936</span><span id="line-936"></span>
<span class="source-line-no">937</span><span id="line-937"> public void testRecoveredEditsReplayCompaction(boolean mismatchedRegionName) throws Exception {</span>
<span class="source-line-no">938</span><span id="line-938"> CONF.setClass(HConstants.REGION_IMPL, HRegionForTesting.class, Region.class);</span>
<span class="source-line-no">939</span><span id="line-939"> byte[] family = Bytes.toBytes("family");</span>
<span class="source-line-no">940</span><span id="line-940"> this.region = initHRegion(tableName, method, CONF, family);</span>
<span class="source-line-no">941</span><span id="line-941"> final WALFactory wals = new WALFactory(CONF, method);</span>
<span class="source-line-no">942</span><span id="line-942"> try {</span>
<span class="source-line-no">943</span><span id="line-943"> Path regiondir = region.getRegionFileSystem().getRegionDir();</span>
<span class="source-line-no">944</span><span id="line-944"> FileSystem fs = region.getRegionFileSystem().getFileSystem();</span>
<span class="source-line-no">945</span><span id="line-945"> byte[] regionName = region.getRegionInfo().getEncodedNameAsBytes();</span>
<span class="source-line-no">946</span><span id="line-946"></span>
<span class="source-line-no">947</span><span id="line-947"> long maxSeqId = 3;</span>
<span class="source-line-no">948</span><span id="line-948"> long minSeqId = 0;</span>
<span class="source-line-no">949</span><span id="line-949"></span>
<span class="source-line-no">950</span><span id="line-950"> for (long i = minSeqId; i &lt; maxSeqId; i++) {</span>
<span class="source-line-no">951</span><span id="line-951"> Put put = new Put(Bytes.toBytes(i));</span>
<span class="source-line-no">952</span><span id="line-952"> put.addColumn(family, Bytes.toBytes(i), Bytes.toBytes(i));</span>
<span class="source-line-no">953</span><span id="line-953"> region.put(put);</span>
<span class="source-line-no">954</span><span id="line-954"> region.flush(true);</span>
<span class="source-line-no">955</span><span id="line-955"> }</span>
<span class="source-line-no">956</span><span id="line-956"></span>
<span class="source-line-no">957</span><span id="line-957"> // this will create a region with 3 files</span>
<span class="source-line-no">958</span><span id="line-958"> assertEquals(3, region.getStore(family).getStorefilesCount());</span>
<span class="source-line-no">959</span><span id="line-959"> List&lt;Path&gt; storeFiles = new ArrayList&lt;&gt;(3);</span>
<span class="source-line-no">960</span><span id="line-960"> for (HStoreFile sf : region.getStore(family).getStorefiles()) {</span>
<span class="source-line-no">961</span><span id="line-961"> storeFiles.add(sf.getPath());</span>
<span class="source-line-no">962</span><span id="line-962"> }</span>
<span class="source-line-no">963</span><span id="line-963"></span>
<span class="source-line-no">964</span><span id="line-964"> // disable compaction completion</span>
<span class="source-line-no">965</span><span id="line-965"> CONF.setBoolean("hbase.hstore.compaction.complete", false);</span>
<span class="source-line-no">966</span><span id="line-966"> region.compactStores();</span>
<span class="source-line-no">967</span><span id="line-967"></span>
<span class="source-line-no">968</span><span id="line-968"> // ensure that nothing changed</span>
<span class="source-line-no">969</span><span id="line-969"> assertEquals(3, region.getStore(family).getStorefilesCount());</span>
<span class="source-line-no">970</span><span id="line-970"></span>
<span class="source-line-no">971</span><span id="line-971"> // now find the compacted file, and manually add it to the recovered edits</span>
<span class="source-line-no">972</span><span id="line-972"> Path tmpDir = new Path(region.getRegionFileSystem().getTempDir(), Bytes.toString(family));</span>
<span class="source-line-no">973</span><span id="line-973"> FileStatus[] files = CommonFSUtils.listStatus(fs, tmpDir);</span>
<span class="source-line-no">974</span><span id="line-974"> String errorMsg = "Expected to find 1 file in the region temp directory "</span>
<span class="source-line-no">975</span><span id="line-975"> + "from the compaction, could not find any";</span>
<span class="source-line-no">976</span><span id="line-976"> assertNotNull(errorMsg, files);</span>
<span class="source-line-no">977</span><span id="line-977"> assertEquals(errorMsg, 1, files.length);</span>
<span class="source-line-no">978</span><span id="line-978"> // move the file inside region dir</span>
<span class="source-line-no">979</span><span id="line-979"> Path newFile =</span>
<span class="source-line-no">980</span><span id="line-980"> region.getRegionFileSystem().commitStoreFile(Bytes.toString(family), files[0].getPath());</span>
<span class="source-line-no">981</span><span id="line-981"></span>
<span class="source-line-no">982</span><span id="line-982"> byte[] encodedNameAsBytes = this.region.getRegionInfo().getEncodedNameAsBytes();</span>
<span class="source-line-no">983</span><span id="line-983"> byte[] fakeEncodedNameAsBytes = new byte[encodedNameAsBytes.length];</span>
<span class="source-line-no">984</span><span id="line-984"> for (int i = 0; i &lt; encodedNameAsBytes.length; i++) {</span>
<span class="source-line-no">985</span><span id="line-985"> // Mix the byte array to have a new encodedName</span>
<span class="source-line-no">986</span><span id="line-986"> fakeEncodedNameAsBytes[i] = (byte) (encodedNameAsBytes[i] + 1);</span>
<span class="source-line-no">987</span><span id="line-987"> }</span>
<span class="source-line-no">988</span><span id="line-988"></span>
<span class="source-line-no">989</span><span id="line-989"> CompactionDescriptor compactionDescriptor = ProtobufUtil.toCompactionDescriptor(</span>
<span class="source-line-no">990</span><span id="line-990"> this.region.getRegionInfo(), mismatchedRegionName ? fakeEncodedNameAsBytes : null, family,</span>
<span class="source-line-no">991</span><span id="line-991"> storeFiles, Lists.newArrayList(newFile),</span>
<span class="source-line-no">992</span><span id="line-992"> region.getRegionFileSystem().getStoreDir(Bytes.toString(family)));</span>
<span class="source-line-no">993</span><span id="line-993"></span>
<span class="source-line-no">994</span><span id="line-994"> WALUtil.writeCompactionMarker(region.getWAL(), this.region.getReplicationScope(),</span>
<span class="source-line-no">995</span><span id="line-995"> this.region.getRegionInfo(), compactionDescriptor, region.getMVCC(), null);</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 recoveredEditsDir = WALSplitUtil.getRegionDirRecoveredEditsDir(regiondir);</span>
<span class="source-line-no">998</span><span id="line-998"></span>
<span class="source-line-no">999</span><span id="line-999"> Path recoveredEdits = new Path(recoveredEditsDir, String.format("%019d", 1000));</span>
<span class="source-line-no">1000</span><span id="line-1000"> fs.create(recoveredEdits);</span>
<span class="source-line-no">1001</span><span id="line-1001"> WALProvider.Writer writer = wals.createRecoveredEditsWriter(fs, recoveredEdits);</span>
<span class="source-line-no">1002</span><span id="line-1002"></span>
<span class="source-line-no">1003</span><span id="line-1003"> long time = System.nanoTime();</span>
<span class="source-line-no">1004</span><span id="line-1004"></span>
<span class="source-line-no">1005</span><span id="line-1005"> writer.append(new WAL.Entry(</span>
<span class="source-line-no">1006</span><span id="line-1006"> new WALKeyImpl(regionName, tableName, 10, time, HConstants.DEFAULT_CLUSTER_ID),</span>
<span class="source-line-no">1007</span><span id="line-1007"> WALEdit.createCompaction(region.getRegionInfo(), compactionDescriptor)));</span>
<span class="source-line-no">1008</span><span id="line-1008"> writer.close();</span>
<span class="source-line-no">1009</span><span id="line-1009"></span>
<span class="source-line-no">1010</span><span id="line-1010"> // close the region now, and reopen again</span>
<span class="source-line-no">1011</span><span id="line-1011"> region.getTableDescriptor();</span>
<span class="source-line-no">1012</span><span id="line-1012"> region.getRegionInfo();</span>
<span class="source-line-no">1013</span><span id="line-1013"> HBaseTestingUtil.closeRegionAndWAL(this.region);</span>
<span class="source-line-no">1014</span><span id="line-1014"> try {</span>
<span class="source-line-no">1015</span><span id="line-1015"> region = HRegion.openHRegion(region, null);</span>
<span class="source-line-no">1016</span><span id="line-1016"> } catch (WrongRegionException wre) {</span>
<span class="source-line-no">1017</span><span id="line-1017"> fail("Matching encoded region name should not have produced WrongRegionException");</span>
<span class="source-line-no">1018</span><span id="line-1018"> }</span>
<span class="source-line-no">1019</span><span id="line-1019"></span>
<span class="source-line-no">1020</span><span id="line-1020"> // now check whether we have only one store file, the compacted one</span>
<span class="source-line-no">1021</span><span id="line-1021"> Collection&lt;HStoreFile&gt; sfs = region.getStore(family).getStorefiles();</span>
<span class="source-line-no">1022</span><span id="line-1022"> for (HStoreFile sf : sfs) {</span>
<span class="source-line-no">1023</span><span id="line-1023"> LOG.info(Objects.toString(sf.getPath()));</span>
<span class="source-line-no">1024</span><span id="line-1024"> }</span>
<span class="source-line-no">1025</span><span id="line-1025"> if (!mismatchedRegionName) {</span>
<span class="source-line-no">1026</span><span id="line-1026"> assertEquals(1, region.getStore(family).getStorefilesCount());</span>
<span class="source-line-no">1027</span><span id="line-1027"> }</span>
<span class="source-line-no">1028</span><span id="line-1028"> files = CommonFSUtils.listStatus(fs, tmpDir);</span>
<span class="source-line-no">1029</span><span id="line-1029"> assertTrue("Expected to find 0 files inside " + tmpDir, files == null || files.length == 0);</span>
<span class="source-line-no">1030</span><span id="line-1030"></span>
<span class="source-line-no">1031</span><span id="line-1031"> for (long i = minSeqId; i &lt; maxSeqId; i++) {</span>
<span class="source-line-no">1032</span><span id="line-1032"> Get get = new Get(Bytes.toBytes(i));</span>
<span class="source-line-no">1033</span><span id="line-1033"> Result result = region.get(get);</span>
<span class="source-line-no">1034</span><span id="line-1034"> byte[] value = result.getValue(family, Bytes.toBytes(i));</span>
<span class="source-line-no">1035</span><span id="line-1035"> assertArrayEquals(Bytes.toBytes(i), value);</span>
<span class="source-line-no">1036</span><span id="line-1036"> }</span>
<span class="source-line-no">1037</span><span id="line-1037"> } finally {</span>
<span class="source-line-no">1038</span><span id="line-1038"> HBaseTestingUtil.closeRegionAndWAL(this.region);</span>
<span class="source-line-no">1039</span><span id="line-1039"> this.region = null;</span>
<span class="source-line-no">1040</span><span id="line-1040"> wals.close();</span>
<span class="source-line-no">1041</span><span id="line-1041"> CONF.setClass(HConstants.REGION_IMPL, HRegion.class, Region.class);</span>
<span class="source-line-no">1042</span><span id="line-1042"> }</span>
<span class="source-line-no">1043</span><span id="line-1043"> }</span>
<span class="source-line-no">1044</span><span id="line-1044"></span>
<span class="source-line-no">1045</span><span id="line-1045"> @Test</span>
<span class="source-line-no">1046</span><span id="line-1046"> public void testFlushMarkers() throws Exception {</span>
<span class="source-line-no">1047</span><span id="line-1047"> // tests that flush markers are written to WAL and handled at recovered edits</span>
<span class="source-line-no">1048</span><span id="line-1048"> byte[] family = Bytes.toBytes("family");</span>
<span class="source-line-no">1049</span><span id="line-1049"> Path logDir = TEST_UTIL.getDataTestDirOnTestFS(method + ".log");</span>
<span class="source-line-no">1050</span><span id="line-1050"> final Configuration walConf = new Configuration(TEST_UTIL.getConfiguration());</span>
<span class="source-line-no">1051</span><span id="line-1051"> CommonFSUtils.setRootDir(walConf, logDir);</span>
<span class="source-line-no">1052</span><span id="line-1052"> final WALFactory wals = new WALFactory(walConf, method);</span>
<span class="source-line-no">1053</span><span id="line-1053"> final WAL wal = wals.getWAL(RegionInfoBuilder.newBuilder(tableName).build());</span>
<span class="source-line-no">1054</span><span id="line-1054"></span>
<span class="source-line-no">1055</span><span id="line-1055"> this.region = initHRegion(tableName, HConstants.EMPTY_START_ROW, HConstants.EMPTY_END_ROW, CONF,</span>
<span class="source-line-no">1056</span><span id="line-1056"> false, Durability.USE_DEFAULT, wal, family);</span>
<span class="source-line-no">1057</span><span id="line-1057"> try {</span>
<span class="source-line-no">1058</span><span id="line-1058"> Path regiondir = region.getRegionFileSystem().getRegionDir();</span>
<span class="source-line-no">1059</span><span id="line-1059"> FileSystem fs = region.getRegionFileSystem().getFileSystem();</span>
<span class="source-line-no">1060</span><span id="line-1060"> byte[] regionName = region.getRegionInfo().getEncodedNameAsBytes();</span>
<span class="source-line-no">1061</span><span id="line-1061"></span>
<span class="source-line-no">1062</span><span id="line-1062"> long maxSeqId = 3;</span>
<span class="source-line-no">1063</span><span id="line-1063"> long minSeqId = 0;</span>
<span class="source-line-no">1064</span><span id="line-1064"></span>
<span class="source-line-no">1065</span><span id="line-1065"> for (long i = minSeqId; i &lt; maxSeqId; i++) {</span>
<span class="source-line-no">1066</span><span id="line-1066"> Put put = new Put(Bytes.toBytes(i));</span>
<span class="source-line-no">1067</span><span id="line-1067"> put.addColumn(family, Bytes.toBytes(i), Bytes.toBytes(i));</span>
<span class="source-line-no">1068</span><span id="line-1068"> region.put(put);</span>
<span class="source-line-no">1069</span><span id="line-1069"> region.flush(true);</span>
<span class="source-line-no">1070</span><span id="line-1070"> }</span>
<span class="source-line-no">1071</span><span id="line-1071"></span>
<span class="source-line-no">1072</span><span id="line-1072"> // this will create a region with 3 files from flush</span>
<span class="source-line-no">1073</span><span id="line-1073"> assertEquals(3, region.getStore(family).getStorefilesCount());</span>
<span class="source-line-no">1074</span><span id="line-1074"> List&lt;String&gt; storeFiles = new ArrayList&lt;&gt;(3);</span>
<span class="source-line-no">1075</span><span id="line-1075"> for (HStoreFile sf : region.getStore(family).getStorefiles()) {</span>
<span class="source-line-no">1076</span><span id="line-1076"> storeFiles.add(sf.getPath().getName());</span>
<span class="source-line-no">1077</span><span id="line-1077"> }</span>
<span class="source-line-no">1078</span><span id="line-1078"></span>
<span class="source-line-no">1079</span><span id="line-1079"> // now verify that the flush markers are written</span>
<span class="source-line-no">1080</span><span id="line-1080"> wal.shutdown();</span>
<span class="source-line-no">1081</span><span id="line-1081"> WALStreamReader reader = WALFactory.createStreamReader(fs,</span>
<span class="source-line-no">1082</span><span id="line-1082"> AbstractFSWALProvider.getCurrentFileName(wal), TEST_UTIL.getConfiguration());</span>
<span class="source-line-no">1083</span><span id="line-1083"> try {</span>
<span class="source-line-no">1084</span><span id="line-1084"> List&lt;WAL.Entry&gt; flushDescriptors = new ArrayList&lt;&gt;();</span>
<span class="source-line-no">1085</span><span id="line-1085"> long lastFlushSeqId = -1;</span>
<span class="source-line-no">1086</span><span id="line-1086"> while (true) {</span>
<span class="source-line-no">1087</span><span id="line-1087"> WAL.Entry entry = reader.next();</span>
<span class="source-line-no">1088</span><span id="line-1088"> if (entry == null) {</span>
<span class="source-line-no">1089</span><span id="line-1089"> break;</span>
<span class="source-line-no">1090</span><span id="line-1090"> }</span>
<span class="source-line-no">1091</span><span id="line-1091"> Cell cell = entry.getEdit().getCells().get(0);</span>
<span class="source-line-no">1092</span><span id="line-1092"> if (WALEdit.isMetaEditFamily(cell)) {</span>
<span class="source-line-no">1093</span><span id="line-1093"> FlushDescriptor flushDesc = WALEdit.getFlushDescriptor(cell);</span>
<span class="source-line-no">1094</span><span id="line-1094"> assertNotNull(flushDesc);</span>
<span class="source-line-no">1095</span><span id="line-1095"> assertArrayEquals(tableName.getName(), flushDesc.getTableName().toByteArray());</span>
<span class="source-line-no">1096</span><span id="line-1096"> if (flushDesc.getAction() == FlushAction.START_FLUSH) {</span>
<span class="source-line-no">1097</span><span id="line-1097"> assertTrue(flushDesc.getFlushSequenceNumber() &gt; lastFlushSeqId);</span>
<span class="source-line-no">1098</span><span id="line-1098"> } else if (flushDesc.getAction() == FlushAction.COMMIT_FLUSH) {</span>
<span class="source-line-no">1099</span><span id="line-1099"> assertTrue(flushDesc.getFlushSequenceNumber() == lastFlushSeqId);</span>
<span class="source-line-no">1100</span><span id="line-1100"> }</span>
<span class="source-line-no">1101</span><span id="line-1101"> lastFlushSeqId = flushDesc.getFlushSequenceNumber();</span>
<span class="source-line-no">1102</span><span id="line-1102"> assertArrayEquals(regionName, flushDesc.getEncodedRegionName().toByteArray());</span>
<span class="source-line-no">1103</span><span id="line-1103"> assertEquals(1, flushDesc.getStoreFlushesCount()); // only one store</span>
<span class="source-line-no">1104</span><span id="line-1104"> StoreFlushDescriptor storeFlushDesc = flushDesc.getStoreFlushes(0);</span>
<span class="source-line-no">1105</span><span id="line-1105"> assertArrayEquals(family, storeFlushDesc.getFamilyName().toByteArray());</span>
<span class="source-line-no">1106</span><span id="line-1106"> assertEquals("family", storeFlushDesc.getStoreHomeDir());</span>
<span class="source-line-no">1107</span><span id="line-1107"> if (flushDesc.getAction() == FlushAction.START_FLUSH) {</span>
<span class="source-line-no">1108</span><span id="line-1108"> assertEquals(0, storeFlushDesc.getFlushOutputCount());</span>
<span class="source-line-no">1109</span><span id="line-1109"> } else {</span>
<span class="source-line-no">1110</span><span id="line-1110"> assertEquals(1, storeFlushDesc.getFlushOutputCount()); // only one file from flush</span>
<span class="source-line-no">1111</span><span id="line-1111"> assertTrue(storeFiles.contains(storeFlushDesc.getFlushOutput(0)));</span>
<span class="source-line-no">1112</span><span id="line-1112"> }</span>
<span class="source-line-no">1113</span><span id="line-1113"></span>
<span class="source-line-no">1114</span><span id="line-1114"> flushDescriptors.add(entry);</span>
<span class="source-line-no">1115</span><span id="line-1115"> }</span>
<span class="source-line-no">1116</span><span id="line-1116"> }</span>
<span class="source-line-no">1117</span><span id="line-1117"></span>
<span class="source-line-no">1118</span><span id="line-1118"> assertEquals(3 * 2, flushDescriptors.size()); // START_FLUSH and COMMIT_FLUSH per flush</span>
<span class="source-line-no">1119</span><span id="line-1119"></span>
<span class="source-line-no">1120</span><span id="line-1120"> // now write those markers to the recovered edits again.</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 recoveredEditsDir = WALSplitUtil.getRegionDirRecoveredEditsDir(regiondir);</span>
<span class="source-line-no">1123</span><span id="line-1123"></span>
<span class="source-line-no">1124</span><span id="line-1124"> Path recoveredEdits = new Path(recoveredEditsDir, String.format("%019d", 1000));</span>
<span class="source-line-no">1125</span><span id="line-1125"> fs.create(recoveredEdits);</span>
<span class="source-line-no">1126</span><span id="line-1126"> WALProvider.Writer writer = wals.createRecoveredEditsWriter(fs, recoveredEdits);</span>
<span class="source-line-no">1127</span><span id="line-1127"></span>
<span class="source-line-no">1128</span><span id="line-1128"> for (WAL.Entry entry : flushDescriptors) {</span>
<span class="source-line-no">1129</span><span id="line-1129"> writer.append(entry);</span>
<span class="source-line-no">1130</span><span id="line-1130"> }</span>
<span class="source-line-no">1131</span><span id="line-1131"> writer.close();</span>
<span class="source-line-no">1132</span><span id="line-1132"> } finally {</span>
<span class="source-line-no">1133</span><span id="line-1133"> reader.close();</span>
<span class="source-line-no">1134</span><span id="line-1134"> }</span>
<span class="source-line-no">1135</span><span id="line-1135"></span>
<span class="source-line-no">1136</span><span id="line-1136"> // close the region now, and reopen again</span>
<span class="source-line-no">1137</span><span id="line-1137"> HBaseTestingUtil.closeRegionAndWAL(this.region);</span>
<span class="source-line-no">1138</span><span id="line-1138"> region = HRegion.openHRegion(region, null);</span>
<span class="source-line-no">1139</span><span id="line-1139"></span>
<span class="source-line-no">1140</span><span id="line-1140"> // now check whether we have can read back the data from region</span>
<span class="source-line-no">1141</span><span id="line-1141"> for (long i = minSeqId; i &lt; maxSeqId; i++) {</span>
<span class="source-line-no">1142</span><span id="line-1142"> Get get = new Get(Bytes.toBytes(i));</span>
<span class="source-line-no">1143</span><span id="line-1143"> Result result = region.get(get);</span>
<span class="source-line-no">1144</span><span id="line-1144"> byte[] value = result.getValue(family, Bytes.toBytes(i));</span>
<span class="source-line-no">1145</span><span id="line-1145"> assertArrayEquals(Bytes.toBytes(i), value);</span>
<span class="source-line-no">1146</span><span id="line-1146"> }</span>
<span class="source-line-no">1147</span><span id="line-1147"> } finally {</span>
<span class="source-line-no">1148</span><span id="line-1148"> HBaseTestingUtil.closeRegionAndWAL(this.region);</span>
<span class="source-line-no">1149</span><span id="line-1149"> this.region = null;</span>
<span class="source-line-no">1150</span><span id="line-1150"> wals.close();</span>
<span class="source-line-no">1151</span><span id="line-1151"> }</span>
<span class="source-line-no">1152</span><span id="line-1152"> }</span>
<span class="source-line-no">1153</span><span id="line-1153"></span>
<span class="source-line-no">1154</span><span id="line-1154"> static class IsFlushWALMarker implements ArgumentMatcher&lt;WALEdit&gt; {</span>
<span class="source-line-no">1155</span><span id="line-1155"> volatile FlushAction[] actions;</span>
<span class="source-line-no">1156</span><span id="line-1156"></span>
<span class="source-line-no">1157</span><span id="line-1157"> public IsFlushWALMarker(FlushAction... actions) {</span>
<span class="source-line-no">1158</span><span id="line-1158"> this.actions = actions;</span>
<span class="source-line-no">1159</span><span id="line-1159"> }</span>
<span class="source-line-no">1160</span><span id="line-1160"></span>
<span class="source-line-no">1161</span><span id="line-1161"> @Override</span>
<span class="source-line-no">1162</span><span id="line-1162"> public boolean matches(WALEdit edit) {</span>
<span class="source-line-no">1163</span><span id="line-1163"> List&lt;Cell&gt; cells = edit.getCells();</span>
<span class="source-line-no">1164</span><span id="line-1164"> if (cells.isEmpty()) {</span>
<span class="source-line-no">1165</span><span id="line-1165"> return false;</span>
<span class="source-line-no">1166</span><span id="line-1166"> }</span>
<span class="source-line-no">1167</span><span id="line-1167"> if (WALEdit.isMetaEditFamily(cells.get(0))) {</span>
<span class="source-line-no">1168</span><span id="line-1168"> FlushDescriptor desc;</span>
<span class="source-line-no">1169</span><span id="line-1169"> try {</span>
<span class="source-line-no">1170</span><span id="line-1170"> desc = WALEdit.getFlushDescriptor(cells.get(0));</span>
<span class="source-line-no">1171</span><span id="line-1171"> } catch (IOException e) {</span>
<span class="source-line-no">1172</span><span id="line-1172"> LOG.warn(e.toString(), e);</span>
<span class="source-line-no">1173</span><span id="line-1173"> return false;</span>
<span class="source-line-no">1174</span><span id="line-1174"> }</span>
<span class="source-line-no">1175</span><span id="line-1175"> if (desc != null) {</span>
<span class="source-line-no">1176</span><span id="line-1176"> for (FlushAction action : actions) {</span>
<span class="source-line-no">1177</span><span id="line-1177"> if (desc.getAction() == action) {</span>
<span class="source-line-no">1178</span><span id="line-1178"> return true;</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"> }</span>
<span class="source-line-no">1182</span><span id="line-1182"> }</span>
<span class="source-line-no">1183</span><span id="line-1183"> return false;</span>
<span class="source-line-no">1184</span><span id="line-1184"> }</span>
<span class="source-line-no">1185</span><span id="line-1185"></span>
<span class="source-line-no">1186</span><span id="line-1186"> public IsFlushWALMarker set(FlushAction... actions) {</span>
<span class="source-line-no">1187</span><span id="line-1187"> this.actions = actions;</span>
<span class="source-line-no">1188</span><span id="line-1188"> return this;</span>
<span class="source-line-no">1189</span><span id="line-1189"> }</span>
<span class="source-line-no">1190</span><span id="line-1190"> }</span>
<span class="source-line-no">1191</span><span id="line-1191"></span>
<span class="source-line-no">1192</span><span id="line-1192"> @Test</span>
<span class="source-line-no">1193</span><span id="line-1193"> public void testFlushMarkersWALFail() throws Exception {</span>
<span class="source-line-no">1194</span><span id="line-1194"> // test the cases where the WAL append for flush markers fail.</span>
<span class="source-line-no">1195</span><span id="line-1195"> byte[] family = Bytes.toBytes("family");</span>
<span class="source-line-no">1196</span><span id="line-1196"></span>
<span class="source-line-no">1197</span><span id="line-1197"> // spy an actual WAL implementation to throw exception (was not able to mock)</span>
<span class="source-line-no">1198</span><span id="line-1198"> Path logDir = TEST_UTIL.getDataTestDirOnTestFS(method + "log");</span>
<span class="source-line-no">1199</span><span id="line-1199"></span>
<span class="source-line-no">1200</span><span id="line-1200"> final Configuration walConf = new Configuration(TEST_UTIL.getConfiguration());</span>
<span class="source-line-no">1201</span><span id="line-1201"> CommonFSUtils.setRootDir(walConf, logDir);</span>
<span class="source-line-no">1202</span><span id="line-1202"> // Make up a WAL that we can manipulate at append time.</span>
<span class="source-line-no">1203</span><span id="line-1203"> class FailAppendFlushMarkerWAL extends FSHLog {</span>
<span class="source-line-no">1204</span><span id="line-1204"> volatile FlushAction[] flushActions = null;</span>
<span class="source-line-no">1205</span><span id="line-1205"></span>
<span class="source-line-no">1206</span><span id="line-1206"> public FailAppendFlushMarkerWAL(FileSystem fs, Path root, String logDir, Configuration conf)</span>
<span class="source-line-no">1207</span><span id="line-1207"> throws IOException {</span>
<span class="source-line-no">1208</span><span id="line-1208"> super(fs, root, logDir, conf);</span>
<span class="source-line-no">1209</span><span id="line-1209"> }</span>
<span class="source-line-no">1210</span><span id="line-1210"></span>
<span class="source-line-no">1211</span><span id="line-1211"> @Override</span>
<span class="source-line-no">1212</span><span id="line-1212"> protected Writer createWriterInstance(FileSystem fs, Path path) throws IOException {</span>
<span class="source-line-no">1213</span><span id="line-1213"> final Writer w = super.createWriterInstance(fs, path);</span>
<span class="source-line-no">1214</span><span id="line-1214"> return new Writer() {</span>
<span class="source-line-no">1215</span><span id="line-1215"> @Override</span>
<span class="source-line-no">1216</span><span id="line-1216"> public void close() throws IOException {</span>
<span class="source-line-no">1217</span><span id="line-1217"> w.close();</span>
<span class="source-line-no">1218</span><span id="line-1218"> }</span>
<span class="source-line-no">1219</span><span id="line-1219"></span>
<span class="source-line-no">1220</span><span id="line-1220"> @Override</span>
<span class="source-line-no">1221</span><span id="line-1221"> public void sync(boolean forceSync) throws IOException {</span>
<span class="source-line-no">1222</span><span id="line-1222"> w.sync(forceSync);</span>
<span class="source-line-no">1223</span><span id="line-1223"> }</span>
<span class="source-line-no">1224</span><span id="line-1224"></span>
<span class="source-line-no">1225</span><span id="line-1225"> @Override</span>
<span class="source-line-no">1226</span><span id="line-1226"> public void append(Entry entry) throws IOException {</span>
<span class="source-line-no">1227</span><span id="line-1227"> List&lt;Cell&gt; cells = entry.getEdit().getCells();</span>
<span class="source-line-no">1228</span><span id="line-1228"> if (WALEdit.isMetaEditFamily(cells.get(0))) {</span>
<span class="source-line-no">1229</span><span id="line-1229"> FlushDescriptor desc = WALEdit.getFlushDescriptor(cells.get(0));</span>
<span class="source-line-no">1230</span><span id="line-1230"> if (desc != null) {</span>
<span class="source-line-no">1231</span><span id="line-1231"> for (FlushAction flushAction : flushActions) {</span>
<span class="source-line-no">1232</span><span id="line-1232"> if (desc.getAction().equals(flushAction)) {</span>
<span class="source-line-no">1233</span><span id="line-1233"> throw new IOException("Failed to append flush marker! " + flushAction);</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"> }</span>
<span class="source-line-no">1237</span><span id="line-1237"> }</span>
<span class="source-line-no">1238</span><span id="line-1238"> w.append(entry);</span>
<span class="source-line-no">1239</span><span id="line-1239"> }</span>
<span class="source-line-no">1240</span><span id="line-1240"></span>
<span class="source-line-no">1241</span><span id="line-1241"> @Override</span>
<span class="source-line-no">1242</span><span id="line-1242"> public long getLength() {</span>
<span class="source-line-no">1243</span><span id="line-1243"> return w.getLength();</span>
<span class="source-line-no">1244</span><span id="line-1244"> }</span>
<span class="source-line-no">1245</span><span id="line-1245"></span>
<span class="source-line-no">1246</span><span id="line-1246"> @Override</span>
<span class="source-line-no">1247</span><span id="line-1247"> public long getSyncedLength() {</span>
<span class="source-line-no">1248</span><span id="line-1248"> return w.getSyncedLength();</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"> }</span>
<span class="source-line-no">1252</span><span id="line-1252"> }</span>
<span class="source-line-no">1253</span><span id="line-1253"> FailAppendFlushMarkerWAL wal = new FailAppendFlushMarkerWAL(FileSystem.get(walConf),</span>
<span class="source-line-no">1254</span><span id="line-1254"> CommonFSUtils.getRootDir(walConf), method, walConf);</span>
<span class="source-line-no">1255</span><span id="line-1255"> wal.init();</span>
<span class="source-line-no">1256</span><span id="line-1256"> this.region = initHRegion(tableName, HConstants.EMPTY_START_ROW, HConstants.EMPTY_END_ROW, CONF,</span>
<span class="source-line-no">1257</span><span id="line-1257"> false, Durability.USE_DEFAULT, wal, family);</span>
<span class="source-line-no">1258</span><span id="line-1258"> int i = 0;</span>
<span class="source-line-no">1259</span><span id="line-1259"> Put put = new Put(Bytes.toBytes(i));</span>
<span class="source-line-no">1260</span><span id="line-1260"> put.setDurability(Durability.SKIP_WAL); // have to skip mocked wal</span>
<span class="source-line-no">1261</span><span id="line-1261"> put.addColumn(family, Bytes.toBytes(i), Bytes.toBytes(i));</span>
<span class="source-line-no">1262</span><span id="line-1262"> region.put(put);</span>
<span class="source-line-no">1263</span><span id="line-1263"></span>
<span class="source-line-no">1264</span><span id="line-1264"> // 1. Test case where START_FLUSH throws exception</span>
<span class="source-line-no">1265</span><span id="line-1265"> wal.flushActions = new FlushAction[] { FlushAction.START_FLUSH };</span>
<span class="source-line-no">1266</span><span id="line-1266"></span>
<span class="source-line-no">1267</span><span id="line-1267"> // start cache flush will throw exception</span>
<span class="source-line-no">1268</span><span id="line-1268"> try {</span>
<span class="source-line-no">1269</span><span id="line-1269"> region.flush(true);</span>
<span class="source-line-no">1270</span><span id="line-1270"> fail("This should have thrown exception");</span>
<span class="source-line-no">1271</span><span id="line-1271"> } catch (DroppedSnapshotException unexpected) {</span>
<span class="source-line-no">1272</span><span id="line-1272"> // this should not be a dropped snapshot exception. Meaning that RS will not abort</span>
<span class="source-line-no">1273</span><span id="line-1273"> throw unexpected;</span>
<span class="source-line-no">1274</span><span id="line-1274"> } catch (IOException expected) {</span>
<span class="source-line-no">1275</span><span id="line-1275"> // expected</span>
<span class="source-line-no">1276</span><span id="line-1276"> }</span>
<span class="source-line-no">1277</span><span id="line-1277"> // The WAL is hosed now. It has two edits appended. We cannot roll the log without it</span>
<span class="source-line-no">1278</span><span id="line-1278"> // throwing a DroppedSnapshotException to force an abort. Just clean up the mess.</span>
<span class="source-line-no">1279</span><span id="line-1279"> region.close(true);</span>
<span class="source-line-no">1280</span><span id="line-1280"> wal.close();</span>
<span class="source-line-no">1281</span><span id="line-1281"> // release the snapshot and active segment, so netty will not report memory leak</span>
<span class="source-line-no">1282</span><span id="line-1282"> for (HStore store : region.getStores()) {</span>
<span class="source-line-no">1283</span><span id="line-1283"> AbstractMemStore memstore = (AbstractMemStore) store.memstore;</span>
<span class="source-line-no">1284</span><span id="line-1284"> memstore.doClearSnapShot();</span>
<span class="source-line-no">1285</span><span id="line-1285"> memstore.close();</span>
<span class="source-line-no">1286</span><span id="line-1286"> }</span>
<span class="source-line-no">1287</span><span id="line-1287"></span>
<span class="source-line-no">1288</span><span id="line-1288"> // 2. Test case where START_FLUSH succeeds but COMMIT_FLUSH will throw exception</span>
<span class="source-line-no">1289</span><span id="line-1289"> wal.flushActions = new FlushAction[] { FlushAction.COMMIT_FLUSH };</span>
<span class="source-line-no">1290</span><span id="line-1290"> wal = new FailAppendFlushMarkerWAL(FileSystem.get(walConf), CommonFSUtils.getRootDir(walConf),</span>
<span class="source-line-no">1291</span><span id="line-1291"> method, walConf);</span>
<span class="source-line-no">1292</span><span id="line-1292"> wal.init();</span>
<span class="source-line-no">1293</span><span id="line-1293"> this.region = initHRegion(tableName, HConstants.EMPTY_START_ROW, HConstants.EMPTY_END_ROW, CONF,</span>
<span class="source-line-no">1294</span><span id="line-1294"> false, Durability.USE_DEFAULT, wal, family);</span>
<span class="source-line-no">1295</span><span id="line-1295"> region.put(put);</span>
<span class="source-line-no">1296</span><span id="line-1296"> // 3. Test case where ABORT_FLUSH will throw exception.</span>
<span class="source-line-no">1297</span><span id="line-1297"> // Even if ABORT_FLUSH throws exception, we should not fail with IOE, but continue with</span>
<span class="source-line-no">1298</span><span id="line-1298"> // DroppedSnapshotException. Below COMMIT_FLUSH will cause flush to abort</span>
<span class="source-line-no">1299</span><span id="line-1299"> wal.flushActions = new FlushAction[] { FlushAction.COMMIT_FLUSH, FlushAction.ABORT_FLUSH };</span>
<span class="source-line-no">1300</span><span id="line-1300"></span>
<span class="source-line-no">1301</span><span id="line-1301"> // we expect this exception, since we were able to write the snapshot, but failed to</span>
<span class="source-line-no">1302</span><span id="line-1302"> // write the flush marker to WAL</span>
<span class="source-line-no">1303</span><span id="line-1303"> assertThrows(DroppedSnapshotException.class, () -&gt; region.flush(true));</span>
<span class="source-line-no">1304</span><span id="line-1304"></span>
<span class="source-line-no">1305</span><span id="line-1305"> region.close(true);</span>
<span class="source-line-no">1306</span><span id="line-1306"> // release the snapshot and active segment, so netty will not report memory leak</span>
<span class="source-line-no">1307</span><span id="line-1307"> for (HStore store : region.getStores()) {</span>
<span class="source-line-no">1308</span><span id="line-1308"> AbstractMemStore memstore = (AbstractMemStore) store.memstore;</span>
<span class="source-line-no">1309</span><span id="line-1309"> memstore.doClearSnapShot();</span>
<span class="source-line-no">1310</span><span id="line-1310"> memstore.close();</span>
<span class="source-line-no">1311</span><span id="line-1311"> }</span>
<span class="source-line-no">1312</span><span id="line-1312"> region = null;</span>
<span class="source-line-no">1313</span><span id="line-1313"> }</span>
<span class="source-line-no">1314</span><span id="line-1314"></span>
<span class="source-line-no">1315</span><span id="line-1315"> @Test</span>
<span class="source-line-no">1316</span><span id="line-1316"> public void testGetWhileRegionClose() throws IOException {</span>
<span class="source-line-no">1317</span><span id="line-1317"> Configuration hc = initSplit();</span>
<span class="source-line-no">1318</span><span id="line-1318"> int numRows = 100;</span>
<span class="source-line-no">1319</span><span id="line-1319"> byte[][] families = { fam1, fam2, fam3 };</span>
<span class="source-line-no">1320</span><span id="line-1320"></span>
<span class="source-line-no">1321</span><span id="line-1321"> // Setting up region</span>
<span class="source-line-no">1322</span><span id="line-1322"> this.region = initHRegion(tableName, method, hc, families);</span>
<span class="source-line-no">1323</span><span id="line-1323"> // Put data in region</span>
<span class="source-line-no">1324</span><span id="line-1324"> final int startRow = 100;</span>
<span class="source-line-no">1325</span><span id="line-1325"> putData(startRow, numRows, qual1, families);</span>
<span class="source-line-no">1326</span><span id="line-1326"> putData(startRow, numRows, qual2, families);</span>
<span class="source-line-no">1327</span><span id="line-1327"> putData(startRow, numRows, qual3, families);</span>
<span class="source-line-no">1328</span><span id="line-1328"> final AtomicBoolean done = new AtomicBoolean(false);</span>
<span class="source-line-no">1329</span><span id="line-1329"> final AtomicInteger gets = new AtomicInteger(0);</span>
<span class="source-line-no">1330</span><span id="line-1330"> GetTillDoneOrException[] threads = new GetTillDoneOrException[10];</span>
<span class="source-line-no">1331</span><span id="line-1331"> try {</span>
<span class="source-line-no">1332</span><span id="line-1332"> // Set ten threads running concurrently getting from the region.</span>
<span class="source-line-no">1333</span><span id="line-1333"> for (int i = 0; i &lt; threads.length / 2; i++) {</span>
<span class="source-line-no">1334</span><span id="line-1334"> threads[i] = new GetTillDoneOrException(i, Bytes.toBytes("" + startRow), done, gets);</span>
<span class="source-line-no">1335</span><span id="line-1335"> threads[i].setDaemon(true);</span>
<span class="source-line-no">1336</span><span id="line-1336"> threads[i].start();</span>
<span class="source-line-no">1337</span><span id="line-1337"> }</span>
<span class="source-line-no">1338</span><span id="line-1338"> // Artificially make the condition by setting closing flag explicitly.</span>
<span class="source-line-no">1339</span><span id="line-1339"> // I can't make the issue happen with a call to region.close().</span>
<span class="source-line-no">1340</span><span id="line-1340"> this.region.closing.set(true);</span>
<span class="source-line-no">1341</span><span id="line-1341"> for (int i = threads.length / 2; i &lt; threads.length; i++) {</span>
<span class="source-line-no">1342</span><span id="line-1342"> threads[i] = new GetTillDoneOrException(i, Bytes.toBytes("" + startRow), done, gets);</span>
<span class="source-line-no">1343</span><span id="line-1343"> threads[i].setDaemon(true);</span>
<span class="source-line-no">1344</span><span id="line-1344"> threads[i].start();</span>
<span class="source-line-no">1345</span><span id="line-1345"> }</span>
<span class="source-line-no">1346</span><span id="line-1346"> } finally {</span>
<span class="source-line-no">1347</span><span id="line-1347"> if (this.region != null) {</span>
<span class="source-line-no">1348</span><span id="line-1348"> HBaseTestingUtil.closeRegionAndWAL(this.region);</span>
<span class="source-line-no">1349</span><span id="line-1349"> this.region = null;</span>
<span class="source-line-no">1350</span><span id="line-1350"> }</span>
<span class="source-line-no">1351</span><span id="line-1351"> }</span>
<span class="source-line-no">1352</span><span id="line-1352"> done.set(true);</span>
<span class="source-line-no">1353</span><span id="line-1353"> for (GetTillDoneOrException t : threads) {</span>
<span class="source-line-no">1354</span><span id="line-1354"> try {</span>
<span class="source-line-no">1355</span><span id="line-1355"> t.join();</span>
<span class="source-line-no">1356</span><span id="line-1356"> } catch (InterruptedException e) {</span>
<span class="source-line-no">1357</span><span id="line-1357"> e.printStackTrace();</span>
<span class="source-line-no">1358</span><span id="line-1358"> }</span>
<span class="source-line-no">1359</span><span id="line-1359"> if (t.e != null) {</span>
<span class="source-line-no">1360</span><span id="line-1360"> LOG.info("Exception=" + t.e);</span>
<span class="source-line-no">1361</span><span id="line-1361"> assertFalse("Found a NPE in " + t.getName(), t.e instanceof NullPointerException);</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"></span>
<span class="source-line-no">1366</span><span id="line-1366"> /*</span>
<span class="source-line-no">1367</span><span id="line-1367"> * Thread that does get on single row until 'done' flag is flipped. If an exception causes us to</span>
<span class="source-line-no">1368</span><span id="line-1368"> * fail, it records it.</span>
<span class="source-line-no">1369</span><span id="line-1369"> */</span>
<span class="source-line-no">1370</span><span id="line-1370"> class GetTillDoneOrException extends Thread {</span>
<span class="source-line-no">1371</span><span id="line-1371"> private final Get g;</span>
<span class="source-line-no">1372</span><span id="line-1372"> private final AtomicBoolean done;</span>
<span class="source-line-no">1373</span><span id="line-1373"> private final AtomicInteger count;</span>
<span class="source-line-no">1374</span><span id="line-1374"> private Exception e;</span>
<span class="source-line-no">1375</span><span id="line-1375"></span>
<span class="source-line-no">1376</span><span id="line-1376"> GetTillDoneOrException(final int i, final byte[] r, final AtomicBoolean d,</span>
<span class="source-line-no">1377</span><span id="line-1377"> final AtomicInteger c) {</span>
<span class="source-line-no">1378</span><span id="line-1378"> super("getter." + i);</span>
<span class="source-line-no">1379</span><span id="line-1379"> this.g = new Get(r);</span>
<span class="source-line-no">1380</span><span id="line-1380"> this.done = d;</span>
<span class="source-line-no">1381</span><span id="line-1381"> this.count = c;</span>
<span class="source-line-no">1382</span><span id="line-1382"> }</span>
<span class="source-line-no">1383</span><span id="line-1383"></span>
<span class="source-line-no">1384</span><span id="line-1384"> @Override</span>
<span class="source-line-no">1385</span><span id="line-1385"> public void run() {</span>
<span class="source-line-no">1386</span><span id="line-1386"> while (!this.done.get()) {</span>
<span class="source-line-no">1387</span><span id="line-1387"> try {</span>
<span class="source-line-no">1388</span><span id="line-1388"> assertTrue(region.get(g).size() &gt; 0);</span>
<span class="source-line-no">1389</span><span id="line-1389"> this.count.incrementAndGet();</span>
<span class="source-line-no">1390</span><span id="line-1390"> } catch (Exception e) {</span>
<span class="source-line-no">1391</span><span id="line-1391"> this.e = e;</span>
<span class="source-line-no">1392</span><span id="line-1392"> break;</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"></span>
<span class="source-line-no">1398</span><span id="line-1398"> /*</span>
<span class="source-line-no">1399</span><span id="line-1399"> * An involved filter test. Has multiple column families and deletes in mix.</span>
<span class="source-line-no">1400</span><span id="line-1400"> */</span>
<span class="source-line-no">1401</span><span id="line-1401"> @Test</span>
<span class="source-line-no">1402</span><span id="line-1402"> public void testWeirdCacheBehaviour() throws Exception {</span>
<span class="source-line-no">1403</span><span id="line-1403"> final TableName tableName = TableName.valueOf(name.getMethodName());</span>
<span class="source-line-no">1404</span><span id="line-1404"> byte[][] FAMILIES = new byte[][] { Bytes.toBytes("trans-blob"), Bytes.toBytes("trans-type"),</span>
<span class="source-line-no">1405</span><span id="line-1405"> Bytes.toBytes("trans-date"), Bytes.toBytes("trans-tags"), Bytes.toBytes("trans-group") };</span>
<span class="source-line-no">1406</span><span id="line-1406"> this.region = initHRegion(tableName, method, CONF, FAMILIES);</span>
<span class="source-line-no">1407</span><span id="line-1407"> String value = "this is the value";</span>
<span class="source-line-no">1408</span><span id="line-1408"> String value2 = "this is some other value";</span>
<span class="source-line-no">1409</span><span id="line-1409"> String keyPrefix1 = "prefix1";</span>
<span class="source-line-no">1410</span><span id="line-1410"> String keyPrefix2 = "prefix2";</span>
<span class="source-line-no">1411</span><span id="line-1411"> String keyPrefix3 = "prefix3";</span>
<span class="source-line-no">1412</span><span id="line-1412"> putRows(this.region, 3, value, keyPrefix1);</span>
<span class="source-line-no">1413</span><span id="line-1413"> putRows(this.region, 3, value, keyPrefix2);</span>
<span class="source-line-no">1414</span><span id="line-1414"> putRows(this.region, 3, value, keyPrefix3);</span>
<span class="source-line-no">1415</span><span id="line-1415"> putRows(this.region, 3, value2, keyPrefix1);</span>
<span class="source-line-no">1416</span><span id="line-1416"> putRows(this.region, 3, value2, keyPrefix2);</span>
<span class="source-line-no">1417</span><span id="line-1417"> putRows(this.region, 3, value2, keyPrefix3);</span>
<span class="source-line-no">1418</span><span id="line-1418"> System.out.println("Checking values for key: " + keyPrefix1);</span>
<span class="source-line-no">1419</span><span id="line-1419"> assertEquals("Got back incorrect number of rows from scan", 3,</span>
<span class="source-line-no">1420</span><span id="line-1420"> getNumberOfRows(keyPrefix1, value2, this.region));</span>
<span class="source-line-no">1421</span><span id="line-1421"> System.out.println("Checking values for key: " + keyPrefix2);</span>
<span class="source-line-no">1422</span><span id="line-1422"> assertEquals("Got back incorrect number of rows from scan", 3,</span>
<span class="source-line-no">1423</span><span id="line-1423"> getNumberOfRows(keyPrefix2, value2, this.region));</span>
<span class="source-line-no">1424</span><span id="line-1424"> System.out.println("Checking values for key: " + keyPrefix3);</span>
<span class="source-line-no">1425</span><span id="line-1425"> assertEquals("Got back incorrect number of rows from scan", 3,</span>
<span class="source-line-no">1426</span><span id="line-1426"> getNumberOfRows(keyPrefix3, value2, this.region));</span>
<span class="source-line-no">1427</span><span id="line-1427"> deleteColumns(this.region, value2, keyPrefix1);</span>
<span class="source-line-no">1428</span><span id="line-1428"> deleteColumns(this.region, value2, keyPrefix2);</span>
<span class="source-line-no">1429</span><span id="line-1429"> deleteColumns(this.region, value2, keyPrefix3);</span>
<span class="source-line-no">1430</span><span id="line-1430"> System.out.println("Starting important checks.....");</span>
<span class="source-line-no">1431</span><span id="line-1431"> assertEquals("Got back incorrect number of rows from scan: " + keyPrefix1, 0,</span>
<span class="source-line-no">1432</span><span id="line-1432"> getNumberOfRows(keyPrefix1, value2, this.region));</span>
<span class="source-line-no">1433</span><span id="line-1433"> assertEquals("Got back incorrect number of rows from scan: " + keyPrefix2, 0,</span>
<span class="source-line-no">1434</span><span id="line-1434"> getNumberOfRows(keyPrefix2, value2, this.region));</span>
<span class="source-line-no">1435</span><span id="line-1435"> assertEquals("Got back incorrect number of rows from scan: " + keyPrefix3, 0,</span>
<span class="source-line-no">1436</span><span id="line-1436"> getNumberOfRows(keyPrefix3, value2, this.region));</span>
<span class="source-line-no">1437</span><span id="line-1437"> }</span>
<span class="source-line-no">1438</span><span id="line-1438"></span>
<span class="source-line-no">1439</span><span id="line-1439"> @Test</span>
<span class="source-line-no">1440</span><span id="line-1440"> public void testAppendWithReadOnlyTable() throws Exception {</span>
<span class="source-line-no">1441</span><span id="line-1441"> final TableName tableName = TableName.valueOf(name.getMethodName());</span>
<span class="source-line-no">1442</span><span id="line-1442"> this.region = initHRegion(tableName, method, CONF, true, Bytes.toBytes("somefamily"));</span>
<span class="source-line-no">1443</span><span id="line-1443"> boolean exceptionCaught = false;</span>
<span class="source-line-no">1444</span><span id="line-1444"> Append append = new Append(Bytes.toBytes("somerow"));</span>
<span class="source-line-no">1445</span><span id="line-1445"> append.setDurability(Durability.SKIP_WAL);</span>
<span class="source-line-no">1446</span><span id="line-1446"> append.addColumn(Bytes.toBytes("somefamily"), Bytes.toBytes("somequalifier"),</span>
<span class="source-line-no">1447</span><span id="line-1447"> Bytes.toBytes("somevalue"));</span>
<span class="source-line-no">1448</span><span id="line-1448"> try {</span>
<span class="source-line-no">1449</span><span id="line-1449"> region.append(append);</span>
<span class="source-line-no">1450</span><span id="line-1450"> } catch (IOException e) {</span>
<span class="source-line-no">1451</span><span id="line-1451"> 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"> assertTrue(exceptionCaught == true);</span>
<span class="source-line-no">1454</span><span id="line-1454"> }</span>
<span class="source-line-no">1455</span><span id="line-1455"></span>
<span class="source-line-no">1456</span><span id="line-1456"> @Test</span>
<span class="source-line-no">1457</span><span id="line-1457"> public void testIncrWithReadOnlyTable() throws Exception {</span>
<span class="source-line-no">1458</span><span id="line-1458"> final TableName tableName = TableName.valueOf(name.getMethodName());</span>
<span class="source-line-no">1459</span><span id="line-1459"> this.region = initHRegion(tableName, method, CONF, true, Bytes.toBytes("somefamily"));</span>
<span class="source-line-no">1460</span><span id="line-1460"> boolean exceptionCaught = false;</span>
<span class="source-line-no">1461</span><span id="line-1461"> Increment inc = new Increment(Bytes.toBytes("somerow"));</span>
<span class="source-line-no">1462</span><span id="line-1462"> inc.setDurability(Durability.SKIP_WAL);</span>
<span class="source-line-no">1463</span><span id="line-1463"> inc.addColumn(Bytes.toBytes("somefamily"), Bytes.toBytes("somequalifier"), 1L);</span>
<span class="source-line-no">1464</span><span id="line-1464"> try {</span>
<span class="source-line-no">1465</span><span id="line-1465"> region.increment(inc);</span>
<span class="source-line-no">1466</span><span id="line-1466"> } catch (IOException e) {</span>
<span class="source-line-no">1467</span><span id="line-1467"> 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"> assertTrue(exceptionCaught == true);</span>
<span class="source-line-no">1470</span><span id="line-1470"> }</span>
<span class="source-line-no">1471</span><span id="line-1471"></span>
<span class="source-line-no">1472</span><span id="line-1472"> private void deleteColumns(HRegion r, String value, String keyPrefix) throws IOException {</span>
<span class="source-line-no">1473</span><span id="line-1473"> int count = 0;</span>
<span class="source-line-no">1474</span><span id="line-1474"> try (InternalScanner scanner = buildScanner(keyPrefix, value, r)) {</span>
<span class="source-line-no">1475</span><span id="line-1475"> boolean more = false;</span>
<span class="source-line-no">1476</span><span id="line-1476"> List&lt;Cell&gt; results = new ArrayList&lt;&gt;();</span>
<span class="source-line-no">1477</span><span id="line-1477"> do {</span>
<span class="source-line-no">1478</span><span id="line-1478"> more = scanner.next(results);</span>
<span class="source-line-no">1479</span><span id="line-1479"> if (results != null &amp;&amp; !results.isEmpty()) {</span>
<span class="source-line-no">1480</span><span id="line-1480"> count++;</span>
<span class="source-line-no">1481</span><span id="line-1481"> } else {</span>
<span class="source-line-no">1482</span><span id="line-1482"> break;</span>
<span class="source-line-no">1483</span><span id="line-1483"> }</span>
<span class="source-line-no">1484</span><span id="line-1484"> Delete delete = new Delete(CellUtil.cloneRow(results.get(0)));</span>
<span class="source-line-no">1485</span><span id="line-1485"> delete.addColumn(Bytes.toBytes("trans-tags"), Bytes.toBytes("qual2"));</span>
<span class="source-line-no">1486</span><span id="line-1486"> r.delete(delete);</span>
<span class="source-line-no">1487</span><span id="line-1487"> results.clear();</span>
<span class="source-line-no">1488</span><span id="line-1488"> } while (more);</span>
<span class="source-line-no">1489</span><span id="line-1489"> }</span>
<span class="source-line-no">1490</span><span id="line-1490"> assertEquals("Did not perform correct number of deletes", 3, count);</span>
<span class="source-line-no">1491</span><span id="line-1491"> }</span>
<span class="source-line-no">1492</span><span id="line-1492"></span>
<span class="source-line-no">1493</span><span id="line-1493"> private int getNumberOfRows(String keyPrefix, String value, HRegion r) throws Exception {</span>
<span class="source-line-no">1494</span><span id="line-1494"> try (InternalScanner resultScanner = buildScanner(keyPrefix, value, r)) {</span>
<span class="source-line-no">1495</span><span id="line-1495"> int numberOfResults = 0;</span>
<span class="source-line-no">1496</span><span id="line-1496"> List&lt;Cell&gt; results = new ArrayList&lt;&gt;();</span>
<span class="source-line-no">1497</span><span id="line-1497"> boolean more = false;</span>
<span class="source-line-no">1498</span><span id="line-1498"> do {</span>
<span class="source-line-no">1499</span><span id="line-1499"> more = resultScanner.next(results);</span>
<span class="source-line-no">1500</span><span id="line-1500"> if (results != null &amp;&amp; !results.isEmpty()) {</span>
<span class="source-line-no">1501</span><span id="line-1501"> numberOfResults++;</span>
<span class="source-line-no">1502</span><span id="line-1502"> } else {</span>
<span class="source-line-no">1503</span><span id="line-1503"> break;</span>
<span class="source-line-no">1504</span><span id="line-1504"> }</span>
<span class="source-line-no">1505</span><span id="line-1505"> for (Cell kv : results) {</span>
<span class="source-line-no">1506</span><span id="line-1506"> LOG.info("kv=" + kv.toString() + ", " + Bytes.toString(CellUtil.cloneValue(kv)));</span>
<span class="source-line-no">1507</span><span id="line-1507"> }</span>
<span class="source-line-no">1508</span><span id="line-1508"> results.clear();</span>
<span class="source-line-no">1509</span><span id="line-1509"> } while (more);</span>
<span class="source-line-no">1510</span><span id="line-1510"> return numberOfResults;</span>
<span class="source-line-no">1511</span><span id="line-1511"> }</span>
<span class="source-line-no">1512</span><span id="line-1512"> }</span>
<span class="source-line-no">1513</span><span id="line-1513"></span>
<span class="source-line-no">1514</span><span id="line-1514"> private InternalScanner buildScanner(String keyPrefix, String value, HRegion r)</span>
<span class="source-line-no">1515</span><span id="line-1515"> throws IOException {</span>
<span class="source-line-no">1516</span><span id="line-1516"> // Defaults FilterList.Operator.MUST_PASS_ALL.</span>
<span class="source-line-no">1517</span><span id="line-1517"> FilterList allFilters = new FilterList();</span>
<span class="source-line-no">1518</span><span id="line-1518"> allFilters.addFilter(new PrefixFilter(Bytes.toBytes(keyPrefix)));</span>
<span class="source-line-no">1519</span><span id="line-1519"> // Only return rows where this column value exists in the row.</span>
<span class="source-line-no">1520</span><span id="line-1520"> SingleColumnValueFilter filter = new SingleColumnValueFilter(Bytes.toBytes("trans-tags"),</span>
<span class="source-line-no">1521</span><span id="line-1521"> Bytes.toBytes("qual2"), CompareOperator.EQUAL, Bytes.toBytes(value));</span>
<span class="source-line-no">1522</span><span id="line-1522"> filter.setFilterIfMissing(true);</span>
<span class="source-line-no">1523</span><span id="line-1523"> allFilters.addFilter(filter);</span>
<span class="source-line-no">1524</span><span id="line-1524"> Scan scan = new Scan();</span>
<span class="source-line-no">1525</span><span id="line-1525"> scan.addFamily(Bytes.toBytes("trans-blob"));</span>
<span class="source-line-no">1526</span><span id="line-1526"> scan.addFamily(Bytes.toBytes("trans-type"));</span>
<span class="source-line-no">1527</span><span id="line-1527"> scan.addFamily(Bytes.toBytes("trans-date"));</span>
<span class="source-line-no">1528</span><span id="line-1528"> scan.addFamily(Bytes.toBytes("trans-tags"));</span>
<span class="source-line-no">1529</span><span id="line-1529"> scan.addFamily(Bytes.toBytes("trans-group"));</span>
<span class="source-line-no">1530</span><span id="line-1530"> scan.setFilter(allFilters);</span>
<span class="source-line-no">1531</span><span id="line-1531"> return r.getScanner(scan);</span>
<span class="source-line-no">1532</span><span id="line-1532"> }</span>
<span class="source-line-no">1533</span><span id="line-1533"></span>
<span class="source-line-no">1534</span><span id="line-1534"> private void putRows(HRegion r, int numRows, String value, String key) throws IOException {</span>
<span class="source-line-no">1535</span><span id="line-1535"> for (int i = 0; i &lt; numRows; i++) {</span>
<span class="source-line-no">1536</span><span id="line-1536"> String row = key + "_" + i/* UUID.randomUUID().toString() */;</span>
<span class="source-line-no">1537</span><span id="line-1537"> System.out.println(String.format("Saving row: %s, with value %s", row, value));</span>
<span class="source-line-no">1538</span><span id="line-1538"> Put put = new Put(Bytes.toBytes(row));</span>
<span class="source-line-no">1539</span><span id="line-1539"> put.setDurability(Durability.SKIP_WAL);</span>
<span class="source-line-no">1540</span><span id="line-1540"> put.addColumn(Bytes.toBytes("trans-blob"), null, Bytes.toBytes("value for blob"));</span>
<span class="source-line-no">1541</span><span id="line-1541"> put.addColumn(Bytes.toBytes("trans-type"), null, Bytes.toBytes("statement"));</span>
<span class="source-line-no">1542</span><span id="line-1542"> put.addColumn(Bytes.toBytes("trans-date"), null, Bytes.toBytes("20090921010101999"));</span>
<span class="source-line-no">1543</span><span id="line-1543"> put.addColumn(Bytes.toBytes("trans-tags"), Bytes.toBytes("qual2"), Bytes.toBytes(value));</span>
<span class="source-line-no">1544</span><span id="line-1544"> put.addColumn(Bytes.toBytes("trans-group"), null, Bytes.toBytes("adhocTransactionGroupId"));</span>
<span class="source-line-no">1545</span><span id="line-1545"> r.put(put);</span>
<span class="source-line-no">1546</span><span id="line-1546"> }</span>
<span class="source-line-no">1547</span><span id="line-1547"> }</span>
<span class="source-line-no">1548</span><span id="line-1548"></span>
<span class="source-line-no">1549</span><span id="line-1549"> @Test</span>
<span class="source-line-no">1550</span><span id="line-1550"> public void testFamilyWithAndWithoutColon() throws Exception {</span>
<span class="source-line-no">1551</span><span id="line-1551"> byte[] cf = Bytes.toBytes(COLUMN_FAMILY);</span>
<span class="source-line-no">1552</span><span id="line-1552"> this.region = initHRegion(tableName, method, CONF, cf);</span>
<span class="source-line-no">1553</span><span id="line-1553"> Put p = new Put(tableName.toBytes());</span>
<span class="source-line-no">1554</span><span id="line-1554"> byte[] cfwithcolon = Bytes.toBytes(COLUMN_FAMILY + ":");</span>
<span class="source-line-no">1555</span><span id="line-1555"> p.addColumn(cfwithcolon, cfwithcolon, cfwithcolon);</span>
<span class="source-line-no">1556</span><span id="line-1556"> boolean exception = false;</span>
<span class="source-line-no">1557</span><span id="line-1557"> try {</span>
<span class="source-line-no">1558</span><span id="line-1558"> this.region.put(p);</span>
<span class="source-line-no">1559</span><span id="line-1559"> } catch (NoSuchColumnFamilyException e) {</span>
<span class="source-line-no">1560</span><span id="line-1560"> exception = true;</span>
<span class="source-line-no">1561</span><span id="line-1561"> }</span>
<span class="source-line-no">1562</span><span id="line-1562"> assertTrue(exception);</span>
<span class="source-line-no">1563</span><span id="line-1563"> }</span>
<span class="source-line-no">1564</span><span id="line-1564"></span>
<span class="source-line-no">1565</span><span id="line-1565"> @Test</span>
<span class="source-line-no">1566</span><span id="line-1566"> public void testBatchPut_whileNoRowLocksHeld() throws IOException {</span>
<span class="source-line-no">1567</span><span id="line-1567"> final Put[] puts = new Put[10];</span>
<span class="source-line-no">1568</span><span id="line-1568"> MetricsWALSource source = CompatibilitySingletonFactory.getInstance(MetricsWALSource.class);</span>
<span class="source-line-no">1569</span><span id="line-1569"> long syncs = prepareRegionForBachPut(puts, source, false);</span>
<span class="source-line-no">1570</span><span id="line-1570"></span>
<span class="source-line-no">1571</span><span id="line-1571"> OperationStatus[] codes = this.region.batchMutate(puts);</span>
<span class="source-line-no">1572</span><span id="line-1572"> assertEquals(10, codes.length);</span>
<span class="source-line-no">1573</span><span id="line-1573"> for (int i = 0; i &lt; 10; i++) {</span>
<span class="source-line-no">1574</span><span id="line-1574"> assertEquals(OperationStatusCode.SUCCESS, codes[i].getOperationStatusCode());</span>
<span class="source-line-no">1575</span><span id="line-1575"> }</span>
<span class="source-line-no">1576</span><span id="line-1576"> metricsAssertHelper.assertCounter("syncTimeNumOps", syncs + 1, source);</span>
<span class="source-line-no">1577</span><span id="line-1577"></span>
<span class="source-line-no">1578</span><span id="line-1578"> LOG.info("Next a batch put with one invalid family");</span>
<span class="source-line-no">1579</span><span id="line-1579"> puts[5].addColumn(Bytes.toBytes("BAD_CF"), qual, value);</span>
<span class="source-line-no">1580</span><span id="line-1580"> codes = this.region.batchMutate(puts);</span>
<span class="source-line-no">1581</span><span id="line-1581"> assertEquals(10, codes.length);</span>
<span class="source-line-no">1582</span><span id="line-1582"> for (int i = 0; i &lt; 10; i++) {</span>
<span class="source-line-no">1583</span><span id="line-1583"> assertEquals((i == 5) ? OperationStatusCode.BAD_FAMILY : OperationStatusCode.SUCCESS,</span>
<span class="source-line-no">1584</span><span id="line-1584"> codes[i].getOperationStatusCode());</span>
<span class="source-line-no">1585</span><span id="line-1585"> }</span>
<span class="source-line-no">1586</span><span id="line-1586"></span>
<span class="source-line-no">1587</span><span id="line-1587"> metricsAssertHelper.assertCounter("syncTimeNumOps", syncs + 2, source);</span>
<span class="source-line-no">1588</span><span id="line-1588"> }</span>
<span class="source-line-no">1589</span><span id="line-1589"></span>
<span class="source-line-no">1590</span><span id="line-1590"> @Test</span>
<span class="source-line-no">1591</span><span id="line-1591"> public void testBatchPut_whileMultipleRowLocksHeld() throws Exception {</span>
<span class="source-line-no">1592</span><span id="line-1592"> final Put[] puts = new Put[10];</span>
<span class="source-line-no">1593</span><span id="line-1593"> MetricsWALSource source = CompatibilitySingletonFactory.getInstance(MetricsWALSource.class);</span>
<span class="source-line-no">1594</span><span id="line-1594"> long syncs = prepareRegionForBachPut(puts, source, false);</span>
<span class="source-line-no">1595</span><span id="line-1595"></span>
<span class="source-line-no">1596</span><span id="line-1596"> puts[5].addColumn(Bytes.toBytes("BAD_CF"), qual, value);</span>
<span class="source-line-no">1597</span><span id="line-1597"></span>
<span class="source-line-no">1598</span><span id="line-1598"> LOG.info("batchPut will have to break into four batches to avoid row locks");</span>
<span class="source-line-no">1599</span><span id="line-1599"> RowLock rowLock1 = region.getRowLock(Bytes.toBytes("row_2"));</span>
<span class="source-line-no">1600</span><span id="line-1600"> RowLock rowLock2 = region.getRowLock(Bytes.toBytes("row_1"));</span>
<span class="source-line-no">1601</span><span id="line-1601"> RowLock rowLock3 = region.getRowLock(Bytes.toBytes("row_3"));</span>
<span class="source-line-no">1602</span><span id="line-1602"> RowLock rowLock4 = region.getRowLock(Bytes.toBytes("row_3"), true);</span>
<span class="source-line-no">1603</span><span id="line-1603"></span>
<span class="source-line-no">1604</span><span id="line-1604"> MultithreadedTestUtil.TestContext ctx = new MultithreadedTestUtil.TestContext(CONF);</span>
<span class="source-line-no">1605</span><span id="line-1605"> final AtomicReference&lt;OperationStatus[]&gt; retFromThread = new AtomicReference&lt;&gt;();</span>
<span class="source-line-no">1606</span><span id="line-1606"> final CountDownLatch startingPuts = new CountDownLatch(1);</span>
<span class="source-line-no">1607</span><span id="line-1607"> final CountDownLatch startingClose = new CountDownLatch(1);</span>
<span class="source-line-no">1608</span><span id="line-1608"> TestThread putter = new TestThread(ctx) {</span>
<span class="source-line-no">1609</span><span id="line-1609"> @Override</span>
<span class="source-line-no">1610</span><span id="line-1610"> public void doWork() throws IOException {</span>
<span class="source-line-no">1611</span><span id="line-1611"> startingPuts.countDown();</span>
<span class="source-line-no">1612</span><span id="line-1612"> retFromThread.set(region.batchMutate(puts));</span>
<span class="source-line-no">1613</span><span id="line-1613"> }</span>
<span class="source-line-no">1614</span><span id="line-1614"> };</span>
<span class="source-line-no">1615</span><span id="line-1615"> LOG.info("...starting put thread while holding locks");</span>
<span class="source-line-no">1616</span><span id="line-1616"> ctx.addThread(putter);</span>
<span class="source-line-no">1617</span><span id="line-1617"> ctx.startThreads();</span>
<span class="source-line-no">1618</span><span id="line-1618"></span>
<span class="source-line-no">1619</span><span id="line-1619"> // Now attempt to close the region from another thread. Prior to HBASE-12565</span>
<span class="source-line-no">1620</span><span id="line-1620"> // this would cause the in-progress batchMutate operation to to fail with</span>
<span class="source-line-no">1621</span><span id="line-1621"> // exception because it use to release and re-acquire the close-guard lock</span>
<span class="source-line-no">1622</span><span id="line-1622"> // between batches. Caller then didn't get status indicating which writes succeeded.</span>
<span class="source-line-no">1623</span><span id="line-1623"> // We now expect this thread to block until the batchMutate call finishes.</span>
<span class="source-line-no">1624</span><span id="line-1624"> Thread regionCloseThread = new TestThread(ctx) {</span>
<span class="source-line-no">1625</span><span id="line-1625"> @Override</span>
<span class="source-line-no">1626</span><span id="line-1626"> public void doWork() {</span>
<span class="source-line-no">1627</span><span id="line-1627"> try {</span>
<span class="source-line-no">1628</span><span id="line-1628"> startingPuts.await();</span>
<span class="source-line-no">1629</span><span id="line-1629"> // Give some time for the batch mutate to get in.</span>
<span class="source-line-no">1630</span><span id="line-1630"> // We don't want to race with the mutate</span>
<span class="source-line-no">1631</span><span id="line-1631"> Thread.sleep(10);</span>
<span class="source-line-no">1632</span><span id="line-1632"> startingClose.countDown();</span>
<span class="source-line-no">1633</span><span id="line-1633"> HBaseTestingUtil.closeRegionAndWAL(region);</span>
<span class="source-line-no">1634</span><span id="line-1634"> region = null;</span>
<span class="source-line-no">1635</span><span id="line-1635"> } catch (IOException 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"> } catch (InterruptedException e) {</span>
<span class="source-line-no">1638</span><span id="line-1638"> throw new RuntimeException(e);</span>
<span class="source-line-no">1639</span><span id="line-1639"> }</span>
<span class="source-line-no">1640</span><span id="line-1640"> }</span>
<span class="source-line-no">1641</span><span id="line-1641"> };</span>
<span class="source-line-no">1642</span><span id="line-1642"> regionCloseThread.start();</span>
<span class="source-line-no">1643</span><span id="line-1643"></span>
<span class="source-line-no">1644</span><span id="line-1644"> startingClose.await();</span>
<span class="source-line-no">1645</span><span id="line-1645"> startingPuts.await();</span>
<span class="source-line-no">1646</span><span id="line-1646"> Thread.sleep(100);</span>
<span class="source-line-no">1647</span><span id="line-1647"> LOG.info("...releasing row lock 1, which should let put thread continue");</span>
<span class="source-line-no">1648</span><span id="line-1648"> rowLock1.release();</span>
<span class="source-line-no">1649</span><span id="line-1649"> rowLock2.release();</span>
<span class="source-line-no">1650</span><span id="line-1650"> rowLock3.release();</span>
<span class="source-line-no">1651</span><span id="line-1651"> waitForCounter(source, "syncTimeNumOps", syncs + 1);</span>
<span class="source-line-no">1652</span><span id="line-1652"></span>
<span class="source-line-no">1653</span><span id="line-1653"> LOG.info("...joining on put thread");</span>
<span class="source-line-no">1654</span><span id="line-1654"> ctx.stop();</span>
<span class="source-line-no">1655</span><span id="line-1655"> regionCloseThread.join();</span>
<span class="source-line-no">1656</span><span id="line-1656"></span>
<span class="source-line-no">1657</span><span id="line-1657"> OperationStatus[] codes = retFromThread.get();</span>
<span class="source-line-no">1658</span><span id="line-1658"> for (int i = 0; i &lt; codes.length; i++) {</span>
<span class="source-line-no">1659</span><span id="line-1659"> assertEquals((i == 5) ? OperationStatusCode.BAD_FAMILY : OperationStatusCode.SUCCESS,</span>
<span class="source-line-no">1660</span><span id="line-1660"> codes[i].getOperationStatusCode());</span>
<span class="source-line-no">1661</span><span id="line-1661"> }</span>
<span class="source-line-no">1662</span><span id="line-1662"> rowLock4.release();</span>
<span class="source-line-no">1663</span><span id="line-1663"> }</span>
<span class="source-line-no">1664</span><span id="line-1664"></span>
<span class="source-line-no">1665</span><span id="line-1665"> private void waitForCounter(MetricsWALSource source, String metricName, long expectedCount)</span>
<span class="source-line-no">1666</span><span id="line-1666"> throws InterruptedException {</span>
<span class="source-line-no">1667</span><span id="line-1667"> long startWait = EnvironmentEdgeManager.currentTime();</span>
<span class="source-line-no">1668</span><span id="line-1668"> long currentCount;</span>
<span class="source-line-no">1669</span><span id="line-1669"> while ((currentCount = metricsAssertHelper.getCounter(metricName, source)) &lt; expectedCount) {</span>
<span class="source-line-no">1670</span><span id="line-1670"> Thread.sleep(100);</span>
<span class="source-line-no">1671</span><span id="line-1671"> if (EnvironmentEdgeManager.currentTime() - startWait &gt; 10000) {</span>
<span class="source-line-no">1672</span><span id="line-1672"> fail(String.format("Timed out waiting for '%s' &gt;= '%s', currentCount=%s", metricName,</span>
<span class="source-line-no">1673</span><span id="line-1673"> expectedCount, currentCount));</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"> }</span>
<span class="source-line-no">1677</span><span id="line-1677"></span>
<span class="source-line-no">1678</span><span id="line-1678"> @Test</span>
<span class="source-line-no">1679</span><span id="line-1679"> public void testAtomicBatchPut() throws IOException {</span>
<span class="source-line-no">1680</span><span id="line-1680"> final Put[] puts = new Put[10];</span>
<span class="source-line-no">1681</span><span id="line-1681"> MetricsWALSource source = CompatibilitySingletonFactory.getInstance(MetricsWALSource.class);</span>
<span class="source-line-no">1682</span><span id="line-1682"> long syncs = prepareRegionForBachPut(puts, source, false);</span>
<span class="source-line-no">1683</span><span id="line-1683"></span>
<span class="source-line-no">1684</span><span id="line-1684"> // 1. Straight forward case, should succeed</span>
<span class="source-line-no">1685</span><span id="line-1685"> OperationStatus[] codes = this.region.batchMutate(puts, true);</span>
<span class="source-line-no">1686</span><span id="line-1686"> assertEquals(10, codes.length);</span>
<span class="source-line-no">1687</span><span id="line-1687"> for (int i = 0; i &lt; 10; i++) {</span>
<span class="source-line-no">1688</span><span id="line-1688"> assertEquals(OperationStatusCode.SUCCESS, codes[i].getOperationStatusCode());</span>
<span class="source-line-no">1689</span><span id="line-1689"> }</span>
<span class="source-line-no">1690</span><span id="line-1690"> metricsAssertHelper.assertCounter("syncTimeNumOps", syncs + 1, source);</span>
<span class="source-line-no">1691</span><span id="line-1691"></span>
<span class="source-line-no">1692</span><span id="line-1692"> // 2. Failed to get lock</span>
<span class="source-line-no">1693</span><span id="line-1693"> RowLock lock = region.getRowLock(Bytes.toBytes("row_" + 3));</span>
<span class="source-line-no">1694</span><span id="line-1694"> // Method {@link HRegion#getRowLock(byte[])} is reentrant. As 'row_3' is locked in this</span>
<span class="source-line-no">1695</span><span id="line-1695"> // thread, need to run {@link HRegion#batchMutate(HRegion.BatchOperation)} in different thread</span>
<span class="source-line-no">1696</span><span id="line-1696"> MultithreadedTestUtil.TestContext ctx = new MultithreadedTestUtil.TestContext(CONF);</span>
<span class="source-line-no">1697</span><span id="line-1697"> final AtomicReference&lt;IOException&gt; retFromThread = new AtomicReference&lt;&gt;();</span>
<span class="source-line-no">1698</span><span id="line-1698"> final CountDownLatch finishedPuts = new CountDownLatch(1);</span>
<span class="source-line-no">1699</span><span id="line-1699"> TestThread putter = new TestThread(ctx) {</span>
<span class="source-line-no">1700</span><span id="line-1700"> @Override</span>
<span class="source-line-no">1701</span><span id="line-1701"> public void doWork() throws IOException {</span>
<span class="source-line-no">1702</span><span id="line-1702"> try {</span>
<span class="source-line-no">1703</span><span id="line-1703"> region.batchMutate(puts, true);</span>
<span class="source-line-no">1704</span><span id="line-1704"> } catch (IOException ioe) {</span>
<span class="source-line-no">1705</span><span id="line-1705"> LOG.error("test failed!", ioe);</span>
<span class="source-line-no">1706</span><span id="line-1706"> retFromThread.set(ioe);</span>
<span class="source-line-no">1707</span><span id="line-1707"> }</span>
<span class="source-line-no">1708</span><span id="line-1708"> finishedPuts.countDown();</span>
<span class="source-line-no">1709</span><span id="line-1709"> }</span>
<span class="source-line-no">1710</span><span id="line-1710"> };</span>
<span class="source-line-no">1711</span><span id="line-1711"> LOG.info("...starting put thread while holding locks");</span>
<span class="source-line-no">1712</span><span id="line-1712"> ctx.addThread(putter);</span>
<span class="source-line-no">1713</span><span id="line-1713"> ctx.startThreads();</span>
<span class="source-line-no">1714</span><span id="line-1714"> LOG.info("...waiting for batch puts while holding locks");</span>
<span class="source-line-no">1715</span><span id="line-1715"> try {</span>
<span class="source-line-no">1716</span><span id="line-1716"> finishedPuts.await();</span>
<span class="source-line-no">1717</span><span id="line-1717"> } catch (InterruptedException e) {</span>
<span class="source-line-no">1718</span><span id="line-1718"> LOG.error("Interrupted!", e);</span>
<span class="source-line-no">1719</span><span id="line-1719"> } finally {</span>
<span class="source-line-no">1720</span><span id="line-1720"> if (lock != null) {</span>
<span class="source-line-no">1721</span><span id="line-1721"> lock.release();</span>
<span class="source-line-no">1722</span><span id="line-1722"> }</span>
<span class="source-line-no">1723</span><span id="line-1723"> }</span>
<span class="source-line-no">1724</span><span id="line-1724"> assertNotNull(retFromThread.get());</span>
<span class="source-line-no">1725</span><span id="line-1725"> metricsAssertHelper.assertCounter("syncTimeNumOps", syncs + 1, source);</span>
<span class="source-line-no">1726</span><span id="line-1726"></span>
<span class="source-line-no">1727</span><span id="line-1727"> // 3. Exception thrown in validation</span>
<span class="source-line-no">1728</span><span id="line-1728"> LOG.info("Next a batch put with one invalid family");</span>
<span class="source-line-no">1729</span><span id="line-1729"> puts[5].addColumn(Bytes.toBytes("BAD_CF"), qual, value);</span>
<span class="source-line-no">1730</span><span id="line-1730"> thrown.expect(NoSuchColumnFamilyException.class);</span>
<span class="source-line-no">1731</span><span id="line-1731"> this.region.batchMutate(puts, true);</span>
<span class="source-line-no">1732</span><span id="line-1732"> }</span>
<span class="source-line-no">1733</span><span id="line-1733"></span>
<span class="source-line-no">1734</span><span id="line-1734"> @Test</span>
<span class="source-line-no">1735</span><span id="line-1735"> public void testBatchPutWithTsSlop() throws Exception {</span>
<span class="source-line-no">1736</span><span id="line-1736"> // add data with a timestamp that is too recent for range. Ensure assert</span>
<span class="source-line-no">1737</span><span id="line-1737"> CONF.setInt("hbase.hregion.keyvalue.timestamp.slop.millisecs", 1000);</span>
<span class="source-line-no">1738</span><span id="line-1738"> final Put[] puts = new Put[10];</span>
<span class="source-line-no">1739</span><span id="line-1739"> MetricsWALSource source = CompatibilitySingletonFactory.getInstance(MetricsWALSource.class);</span>
<span class="source-line-no">1740</span><span id="line-1740"></span>
<span class="source-line-no">1741</span><span id="line-1741"> long syncs = prepareRegionForBachPut(puts, source, true);</span>
<span class="source-line-no">1742</span><span id="line-1742"></span>
<span class="source-line-no">1743</span><span id="line-1743"> OperationStatus[] codes = this.region.batchMutate(puts);</span>
<span class="source-line-no">1744</span><span id="line-1744"> assertEquals(10, codes.length);</span>
<span class="source-line-no">1745</span><span id="line-1745"> for (int i = 0; i &lt; 10; i++) {</span>
<span class="source-line-no">1746</span><span id="line-1746"> assertEquals(OperationStatusCode.SANITY_CHECK_FAILURE, codes[i].getOperationStatusCode());</span>
<span class="source-line-no">1747</span><span id="line-1747"> }</span>
<span class="source-line-no">1748</span><span id="line-1748"> metricsAssertHelper.assertCounter("syncTimeNumOps", syncs, source);</span>
<span class="source-line-no">1749</span><span id="line-1749"> }</span>
<span class="source-line-no">1750</span><span id="line-1750"></span>
<span class="source-line-no">1751</span><span id="line-1751"> /** Returns syncs initial syncTimeNumOps */</span>
<span class="source-line-no">1752</span><span id="line-1752"> private long prepareRegionForBachPut(final Put[] puts, final MetricsWALSource source,</span>
<span class="source-line-no">1753</span><span id="line-1753"> boolean slop) throws IOException {</span>
<span class="source-line-no">1754</span><span id="line-1754"> this.region = initHRegion(tableName, method, CONF, COLUMN_FAMILY_BYTES);</span>
<span class="source-line-no">1755</span><span id="line-1755"></span>
<span class="source-line-no">1756</span><span id="line-1756"> LOG.info("First a batch put with all valid puts");</span>
<span class="source-line-no">1757</span><span id="line-1757"> for (int i = 0; i &lt; puts.length; i++) {</span>
<span class="source-line-no">1758</span><span id="line-1758"> puts[i] = slop</span>
<span class="source-line-no">1759</span><span id="line-1759"> ? new Put(Bytes.toBytes("row_" + i), Long.MAX_VALUE - 100)</span>
<span class="source-line-no">1760</span><span id="line-1760"> : new Put(Bytes.toBytes("row_" + i));</span>
<span class="source-line-no">1761</span><span id="line-1761"> puts[i].addColumn(COLUMN_FAMILY_BYTES, qual, value);</span>
<span class="source-line-no">1762</span><span id="line-1762"> }</span>
<span class="source-line-no">1763</span><span id="line-1763"></span>
<span class="source-line-no">1764</span><span id="line-1764"> long syncs = metricsAssertHelper.getCounter("syncTimeNumOps", source);</span>
<span class="source-line-no">1765</span><span id="line-1765"> metricsAssertHelper.assertCounter("syncTimeNumOps", syncs, source);</span>
<span class="source-line-no">1766</span><span id="line-1766"> return syncs;</span>
<span class="source-line-no">1767</span><span id="line-1767"> }</span>
<span class="source-line-no">1768</span><span id="line-1768"></span>
<span class="source-line-no">1769</span><span id="line-1769"> // ////////////////////////////////////////////////////////////////////////////</span>
<span class="source-line-no">1770</span><span id="line-1770"> // checkAndMutate tests</span>
<span class="source-line-no">1771</span><span id="line-1771"> // ////////////////////////////////////////////////////////////////////////////</span>
<span class="source-line-no">1772</span><span id="line-1772"> @Test</span>
<span class="source-line-no">1773</span><span id="line-1773"> @Deprecated</span>
<span class="source-line-no">1774</span><span id="line-1774"> public void testCheckAndMutate_WithEmptyRowValue() throws IOException {</span>
<span class="source-line-no">1775</span><span id="line-1775"> byte[] row1 = Bytes.toBytes("row1");</span>
<span class="source-line-no">1776</span><span id="line-1776"> byte[] fam1 = Bytes.toBytes("fam1");</span>
<span class="source-line-no">1777</span><span id="line-1777"> byte[] qf1 = Bytes.toBytes("qualifier");</span>
<span class="source-line-no">1778</span><span id="line-1778"> byte[] emptyVal = new byte[] {};</span>
<span class="source-line-no">1779</span><span id="line-1779"> byte[] val1 = Bytes.toBytes("value1");</span>
<span class="source-line-no">1780</span><span id="line-1780"> byte[] val2 = Bytes.toBytes("value2");</span>
<span class="source-line-no">1781</span><span id="line-1781"></span>
<span class="source-line-no">1782</span><span id="line-1782"> // Setting up region</span>
<span class="source-line-no">1783</span><span id="line-1783"> this.region = initHRegion(tableName, method, CONF, fam1);</span>
<span class="source-line-no">1784</span><span id="line-1784"> // Putting empty data in key</span>
<span class="source-line-no">1785</span><span id="line-1785"> Put put = new Put(row1);</span>
<span class="source-line-no">1786</span><span id="line-1786"> put.addColumn(fam1, qf1, emptyVal);</span>
<span class="source-line-no">1787</span><span id="line-1787"></span>
<span class="source-line-no">1788</span><span id="line-1788"> // checkAndPut with empty value</span>
<span class="source-line-no">1789</span><span id="line-1789"> boolean res = region.checkAndMutate(row1, fam1, qf1, CompareOperator.EQUAL,</span>
<span class="source-line-no">1790</span><span id="line-1790"> new BinaryComparator(emptyVal), put);</span>
<span class="source-line-no">1791</span><span id="line-1791"> assertTrue(res);</span>
<span class="source-line-no">1792</span><span id="line-1792"></span>
<span class="source-line-no">1793</span><span id="line-1793"> // Putting data in key</span>
<span class="source-line-no">1794</span><span id="line-1794"> put = new Put(row1);</span>
<span class="source-line-no">1795</span><span id="line-1795"> put.addColumn(fam1, qf1, val1);</span>
<span class="source-line-no">1796</span><span id="line-1796"></span>
<span class="source-line-no">1797</span><span id="line-1797"> // checkAndPut with correct value</span>
<span class="source-line-no">1798</span><span id="line-1798"> res = region.checkAndMutate(row1, fam1, qf1, CompareOperator.EQUAL,</span>
<span class="source-line-no">1799</span><span id="line-1799"> new BinaryComparator(emptyVal), put);</span>
<span class="source-line-no">1800</span><span id="line-1800"> assertTrue(res);</span>
<span class="source-line-no">1801</span><span id="line-1801"></span>
<span class="source-line-no">1802</span><span id="line-1802"> // not empty anymore</span>
<span class="source-line-no">1803</span><span id="line-1803"> res = region.checkAndMutate(row1, fam1, qf1, CompareOperator.EQUAL,</span>
<span class="source-line-no">1804</span><span id="line-1804"> new BinaryComparator(emptyVal), put);</span>
<span class="source-line-no">1805</span><span id="line-1805"> assertFalse(res);</span>
<span class="source-line-no">1806</span><span id="line-1806"></span>
<span class="source-line-no">1807</span><span id="line-1807"> Delete delete = new Delete(row1);</span>
<span class="source-line-no">1808</span><span id="line-1808"> delete.addColumn(fam1, qf1);</span>
<span class="source-line-no">1809</span><span id="line-1809"> res = region.checkAndMutate(row1, fam1, qf1, CompareOperator.EQUAL,</span>
<span class="source-line-no">1810</span><span id="line-1810"> new BinaryComparator(emptyVal), delete);</span>
<span class="source-line-no">1811</span><span id="line-1811"> assertFalse(res);</span>
<span class="source-line-no">1812</span><span id="line-1812"></span>
<span class="source-line-no">1813</span><span id="line-1813"> put = new Put(row1);</span>
<span class="source-line-no">1814</span><span id="line-1814"> put.addColumn(fam1, qf1, val2);</span>
<span class="source-line-no">1815</span><span id="line-1815"> // checkAndPut with correct value</span>
<span class="source-line-no">1816</span><span id="line-1816"> res = region.checkAndMutate(row1, fam1, qf1, CompareOperator.EQUAL, new BinaryComparator(val1),</span>
<span class="source-line-no">1817</span><span id="line-1817"> put);</span>
<span class="source-line-no">1818</span><span id="line-1818"> assertTrue(res);</span>
<span class="source-line-no">1819</span><span id="line-1819"></span>
<span class="source-line-no">1820</span><span id="line-1820"> // checkAndDelete with correct value</span>
<span class="source-line-no">1821</span><span id="line-1821"> delete = new Delete(row1);</span>
<span class="source-line-no">1822</span><span id="line-1822"> delete.addColumn(fam1, qf1);</span>
<span class="source-line-no">1823</span><span id="line-1823"> delete.addColumn(fam1, qf1);</span>
<span class="source-line-no">1824</span><span id="line-1824"> res = region.checkAndMutate(row1, fam1, qf1, CompareOperator.EQUAL, new BinaryComparator(val2),</span>
<span class="source-line-no">1825</span><span id="line-1825"> delete);</span>
<span class="source-line-no">1826</span><span id="line-1826"> assertTrue(res);</span>
<span class="source-line-no">1827</span><span id="line-1827"></span>
<span class="source-line-no">1828</span><span id="line-1828"> delete = new Delete(row1);</span>
<span class="source-line-no">1829</span><span id="line-1829"> res = region.checkAndMutate(row1, fam1, qf1, CompareOperator.EQUAL,</span>
<span class="source-line-no">1830</span><span id="line-1830"> new BinaryComparator(emptyVal), delete);</span>
<span class="source-line-no">1831</span><span id="line-1831"> assertTrue(res);</span>
<span class="source-line-no">1832</span><span id="line-1832"></span>
<span class="source-line-no">1833</span><span id="line-1833"> // checkAndPut looking for a null value</span>
<span class="source-line-no">1834</span><span id="line-1834"> put = new Put(row1);</span>
<span class="source-line-no">1835</span><span id="line-1835"> put.addColumn(fam1, qf1, val1);</span>
<span class="source-line-no">1836</span><span id="line-1836"></span>
<span class="source-line-no">1837</span><span id="line-1837"> res = region.checkAndMutate(row1, fam1, qf1, CompareOperator.EQUAL, new NullComparator(), put);</span>
<span class="source-line-no">1838</span><span id="line-1838"> assertTrue(res);</span>
<span class="source-line-no">1839</span><span id="line-1839"> }</span>
<span class="source-line-no">1840</span><span id="line-1840"></span>
<span class="source-line-no">1841</span><span id="line-1841"> @Test</span>
<span class="source-line-no">1842</span><span id="line-1842"> @Deprecated</span>
<span class="source-line-no">1843</span><span id="line-1843"> public void testCheckAndMutate_WithWrongValue() throws IOException {</span>
<span class="source-line-no">1844</span><span id="line-1844"> byte[] row1 = Bytes.toBytes("row1");</span>
<span class="source-line-no">1845</span><span id="line-1845"> byte[] fam1 = Bytes.toBytes("fam1");</span>
<span class="source-line-no">1846</span><span id="line-1846"> byte[] qf1 = Bytes.toBytes("qualifier");</span>
<span class="source-line-no">1847</span><span id="line-1847"> byte[] val1 = Bytes.toBytes("value1");</span>
<span class="source-line-no">1848</span><span id="line-1848"> byte[] val2 = Bytes.toBytes("value2");</span>
<span class="source-line-no">1849</span><span id="line-1849"> BigDecimal bd1 = new BigDecimal(Double.MAX_VALUE);</span>
<span class="source-line-no">1850</span><span id="line-1850"> BigDecimal bd2 = new BigDecimal(Double.MIN_VALUE);</span>
<span class="source-line-no">1851</span><span id="line-1851"></span>
<span class="source-line-no">1852</span><span id="line-1852"> // Setting up region</span>
<span class="source-line-no">1853</span><span id="line-1853"> this.region = initHRegion(tableName, method, CONF, fam1);</span>
<span class="source-line-no">1854</span><span id="line-1854"> // Putting data in key</span>
<span class="source-line-no">1855</span><span id="line-1855"> Put put = new Put(row1);</span>
<span class="source-line-no">1856</span><span id="line-1856"> put.addColumn(fam1, qf1, val1);</span>
<span class="source-line-no">1857</span><span id="line-1857"> region.put(put);</span>
<span class="source-line-no">1858</span><span id="line-1858"></span>
<span class="source-line-no">1859</span><span id="line-1859"> // checkAndPut with wrong value</span>
<span class="source-line-no">1860</span><span id="line-1860"> boolean res = region.checkAndMutate(row1, fam1, qf1, CompareOperator.EQUAL,</span>
<span class="source-line-no">1861</span><span id="line-1861"> new BinaryComparator(val2), put);</span>
<span class="source-line-no">1862</span><span id="line-1862"> assertEquals(false, res);</span>
<span class="source-line-no">1863</span><span id="line-1863"></span>
<span class="source-line-no">1864</span><span id="line-1864"> // checkAndDelete with wrong value</span>
<span class="source-line-no">1865</span><span id="line-1865"> Delete delete = new Delete(row1);</span>
<span class="source-line-no">1866</span><span id="line-1866"> delete.addFamily(fam1);</span>
<span class="source-line-no">1867</span><span id="line-1867"> res = region.checkAndMutate(row1, fam1, qf1, CompareOperator.EQUAL, new BinaryComparator(val2),</span>
<span class="source-line-no">1868</span><span id="line-1868"> put);</span>
<span class="source-line-no">1869</span><span id="line-1869"> assertEquals(false, res);</span>
<span class="source-line-no">1870</span><span id="line-1870"></span>
<span class="source-line-no">1871</span><span id="line-1871"> // Putting data in key</span>
<span class="source-line-no">1872</span><span id="line-1872"> put = new Put(row1);</span>
<span class="source-line-no">1873</span><span id="line-1873"> put.addColumn(fam1, qf1, Bytes.toBytes(bd1));</span>
<span class="source-line-no">1874</span><span id="line-1874"> region.put(put);</span>
<span class="source-line-no">1875</span><span id="line-1875"></span>
<span class="source-line-no">1876</span><span id="line-1876"> // checkAndPut with wrong value</span>
<span class="source-line-no">1877</span><span id="line-1877"> res = region.checkAndMutate(row1, fam1, qf1, CompareOperator.EQUAL,</span>
<span class="source-line-no">1878</span><span id="line-1878"> new BigDecimalComparator(bd2), put);</span>
<span class="source-line-no">1879</span><span id="line-1879"> assertEquals(false, res);</span>
<span class="source-line-no">1880</span><span id="line-1880"></span>
<span class="source-line-no">1881</span><span id="line-1881"> // checkAndDelete with wrong value</span>
<span class="source-line-no">1882</span><span id="line-1882"> delete = new Delete(row1);</span>
<span class="source-line-no">1883</span><span id="line-1883"> delete.addFamily(fam1);</span>
<span class="source-line-no">1884</span><span id="line-1884"> res = region.checkAndMutate(row1, fam1, qf1, CompareOperator.EQUAL,</span>
<span class="source-line-no">1885</span><span id="line-1885"> new BigDecimalComparator(bd2), put);</span>
<span class="source-line-no">1886</span><span id="line-1886"> assertEquals(false, res);</span>
<span class="source-line-no">1887</span><span id="line-1887"> }</span>
<span class="source-line-no">1888</span><span id="line-1888"></span>
<span class="source-line-no">1889</span><span id="line-1889"> @Test</span>
<span class="source-line-no">1890</span><span id="line-1890"> @Deprecated</span>
<span class="source-line-no">1891</span><span id="line-1891"> public void testCheckAndMutate_WithCorrectValue() throws IOException {</span>
<span class="source-line-no">1892</span><span id="line-1892"> byte[] row1 = Bytes.toBytes("row1");</span>
<span class="source-line-no">1893</span><span id="line-1893"> byte[] fam1 = Bytes.toBytes("fam1");</span>
<span class="source-line-no">1894</span><span id="line-1894"> byte[] qf1 = Bytes.toBytes("qualifier");</span>
<span class="source-line-no">1895</span><span id="line-1895"> byte[] val1 = Bytes.toBytes("value1");</span>
<span class="source-line-no">1896</span><span id="line-1896"> BigDecimal bd1 = new BigDecimal(Double.MIN_VALUE);</span>
<span class="source-line-no">1897</span><span id="line-1897"></span>
<span class="source-line-no">1898</span><span id="line-1898"> // Setting up region</span>
<span class="source-line-no">1899</span><span id="line-1899"> this.region = initHRegion(tableName, method, CONF, fam1);</span>
<span class="source-line-no">1900</span><span id="line-1900"> // Putting data in key</span>
<span class="source-line-no">1901</span><span id="line-1901"> long now = EnvironmentEdgeManager.currentTime();</span>
<span class="source-line-no">1902</span><span id="line-1902"> Put put = new Put(row1);</span>
<span class="source-line-no">1903</span><span id="line-1903"> put.addColumn(fam1, qf1, now, val1);</span>
<span class="source-line-no">1904</span><span id="line-1904"> region.put(put);</span>
<span class="source-line-no">1905</span><span id="line-1905"></span>
<span class="source-line-no">1906</span><span id="line-1906"> // checkAndPut with correct value</span>
<span class="source-line-no">1907</span><span id="line-1907"> boolean res = region.checkAndMutate(row1, fam1, qf1, CompareOperator.EQUAL,</span>
<span class="source-line-no">1908</span><span id="line-1908"> new BinaryComparator(val1), put);</span>
<span class="source-line-no">1909</span><span id="line-1909"> assertEquals("First", true, res);</span>
<span class="source-line-no">1910</span><span id="line-1910"></span>
<span class="source-line-no">1911</span><span id="line-1911"> // checkAndDelete with correct value</span>
<span class="source-line-no">1912</span><span id="line-1912"> Delete delete = new Delete(row1, now + 1);</span>
<span class="source-line-no">1913</span><span id="line-1913"> delete.addColumn(fam1, qf1);</span>
<span class="source-line-no">1914</span><span id="line-1914"> res = region.checkAndMutate(row1, fam1, qf1, CompareOperator.EQUAL, new BinaryComparator(val1),</span>
<span class="source-line-no">1915</span><span id="line-1915"> delete);</span>
<span class="source-line-no">1916</span><span id="line-1916"> assertEquals("Delete", true, res);</span>
<span class="source-line-no">1917</span><span id="line-1917"></span>
<span class="source-line-no">1918</span><span id="line-1918"> // Putting data in key</span>
<span class="source-line-no">1919</span><span id="line-1919"> put = new Put(row1);</span>
<span class="source-line-no">1920</span><span id="line-1920"> put.addColumn(fam1, qf1, now + 2, Bytes.toBytes(bd1));</span>
<span class="source-line-no">1921</span><span id="line-1921"> region.put(put);</span>
<span class="source-line-no">1922</span><span id="line-1922"></span>
<span class="source-line-no">1923</span><span id="line-1923"> // checkAndPut with correct value</span>
<span class="source-line-no">1924</span><span id="line-1924"> res = region.checkAndMutate(row1, fam1, qf1, CompareOperator.EQUAL,</span>
<span class="source-line-no">1925</span><span id="line-1925"> new BigDecimalComparator(bd1), put);</span>
<span class="source-line-no">1926</span><span id="line-1926"> assertEquals("Second put", true, res);</span>
<span class="source-line-no">1927</span><span id="line-1927"></span>
<span class="source-line-no">1928</span><span id="line-1928"> // checkAndDelete with correct value</span>
<span class="source-line-no">1929</span><span id="line-1929"> delete = new Delete(row1, now + 3);</span>
<span class="source-line-no">1930</span><span id="line-1930"> delete.addColumn(fam1, qf1);</span>
<span class="source-line-no">1931</span><span id="line-1931"> res = region.checkAndMutate(row1, fam1, qf1, CompareOperator.EQUAL,</span>
<span class="source-line-no">1932</span><span id="line-1932"> new BigDecimalComparator(bd1), delete);</span>
<span class="source-line-no">1933</span><span id="line-1933"> assertEquals("Second delete", true, res);</span>
<span class="source-line-no">1934</span><span id="line-1934"> }</span>
<span class="source-line-no">1935</span><span id="line-1935"></span>
<span class="source-line-no">1936</span><span id="line-1936"> @Test</span>
<span class="source-line-no">1937</span><span id="line-1937"> @Deprecated</span>
<span class="source-line-no">1938</span><span id="line-1938"> public void testCheckAndMutate_WithNonEqualCompareOp() throws IOException {</span>
<span class="source-line-no">1939</span><span id="line-1939"> byte[] row1 = Bytes.toBytes("row1");</span>
<span class="source-line-no">1940</span><span id="line-1940"> byte[] fam1 = Bytes.toBytes("fam1");</span>
<span class="source-line-no">1941</span><span id="line-1941"> byte[] qf1 = Bytes.toBytes("qualifier");</span>
<span class="source-line-no">1942</span><span id="line-1942"> byte[] val1 = Bytes.toBytes("value1");</span>
<span class="source-line-no">1943</span><span id="line-1943"> byte[] val2 = Bytes.toBytes("value2");</span>
<span class="source-line-no">1944</span><span id="line-1944"> byte[] val3 = Bytes.toBytes("value3");</span>
<span class="source-line-no">1945</span><span id="line-1945"> byte[] val4 = Bytes.toBytes("value4");</span>
<span class="source-line-no">1946</span><span id="line-1946"></span>
<span class="source-line-no">1947</span><span id="line-1947"> // Setting up region</span>
<span class="source-line-no">1948</span><span id="line-1948"> this.region = initHRegion(tableName, method, CONF, fam1);</span>
<span class="source-line-no">1949</span><span id="line-1949"> // Putting val3 in key</span>
<span class="source-line-no">1950</span><span id="line-1950"> Put put = new Put(row1);</span>
<span class="source-line-no">1951</span><span id="line-1951"> put.addColumn(fam1, qf1, val3);</span>
<span class="source-line-no">1952</span><span id="line-1952"> region.put(put);</span>
<span class="source-line-no">1953</span><span id="line-1953"></span>
<span class="source-line-no">1954</span><span id="line-1954"> // Test CompareOp.LESS: original = val3, compare with val3, fail</span>
<span class="source-line-no">1955</span><span id="line-1955"> boolean res =</span>
<span class="source-line-no">1956</span><span id="line-1956"> region.checkAndMutate(row1, fam1, qf1, CompareOperator.LESS, new BinaryComparator(val3), put);</span>
<span class="source-line-no">1957</span><span id="line-1957"> assertEquals(false, res);</span>
<span class="source-line-no">1958</span><span id="line-1958"></span>
<span class="source-line-no">1959</span><span id="line-1959"> // Test CompareOp.LESS: original = val3, compare with val4, fail</span>
<span class="source-line-no">1960</span><span id="line-1960"> res =</span>
<span class="source-line-no">1961</span><span id="line-1961"> region.checkAndMutate(row1, fam1, qf1, CompareOperator.LESS, new BinaryComparator(val4), put);</span>
<span class="source-line-no">1962</span><span id="line-1962"> assertEquals(false, res);</span>
<span class="source-line-no">1963</span><span id="line-1963"></span>
<span class="source-line-no">1964</span><span id="line-1964"> // Test CompareOp.LESS: original = val3, compare with val2,</span>
<span class="source-line-no">1965</span><span id="line-1965"> // succeed (now value = val2)</span>
<span class="source-line-no">1966</span><span id="line-1966"> put = new Put(row1);</span>
<span class="source-line-no">1967</span><span id="line-1967"> put.addColumn(fam1, qf1, val2);</span>
<span class="source-line-no">1968</span><span id="line-1968"> res =</span>
<span class="source-line-no">1969</span><span id="line-1969"> region.checkAndMutate(row1, fam1, qf1, CompareOperator.LESS, new BinaryComparator(val2), put);</span>
<span class="source-line-no">1970</span><span id="line-1970"> assertEquals(true, res);</span>
<span class="source-line-no">1971</span><span id="line-1971"></span>
<span class="source-line-no">1972</span><span id="line-1972"> // Test CompareOp.LESS_OR_EQUAL: original = val2, compare with val3, fail</span>
<span class="source-line-no">1973</span><span id="line-1973"> res = region.checkAndMutate(row1, fam1, qf1, CompareOperator.LESS_OR_EQUAL,</span>
<span class="source-line-no">1974</span><span id="line-1974"> new BinaryComparator(val3), put);</span>
<span class="source-line-no">1975</span><span id="line-1975"> assertEquals(false, res);</span>
<span class="source-line-no">1976</span><span id="line-1976"></span>
<span class="source-line-no">1977</span><span id="line-1977"> // Test CompareOp.LESS_OR_EQUAL: original = val2, compare with val2,</span>
<span class="source-line-no">1978</span><span id="line-1978"> // succeed (value still = val2)</span>
<span class="source-line-no">1979</span><span id="line-1979"> res = region.checkAndMutate(row1, fam1, qf1, CompareOperator.LESS_OR_EQUAL,</span>
<span class="source-line-no">1980</span><span id="line-1980"> new BinaryComparator(val2), put);</span>
<span class="source-line-no">1981</span><span id="line-1981"> assertEquals(true, res);</span>
<span class="source-line-no">1982</span><span id="line-1982"></span>
<span class="source-line-no">1983</span><span id="line-1983"> // Test CompareOp.LESS_OR_EQUAL: original = val2, compare with val1,</span>
<span class="source-line-no">1984</span><span id="line-1984"> // succeed (now value = val3)</span>
<span class="source-line-no">1985</span><span id="line-1985"> put = new Put(row1);</span>
<span class="source-line-no">1986</span><span id="line-1986"> put.addColumn(fam1, qf1, val3);</span>
<span class="source-line-no">1987</span><span id="line-1987"> res = region.checkAndMutate(row1, fam1, qf1, CompareOperator.LESS_OR_EQUAL,</span>
<span class="source-line-no">1988</span><span id="line-1988"> new BinaryComparator(val1), put);</span>
<span class="source-line-no">1989</span><span id="line-1989"> assertEquals(true, res);</span>
<span class="source-line-no">1990</span><span id="line-1990"></span>
<span class="source-line-no">1991</span><span id="line-1991"> // Test CompareOp.GREATER: original = val3, compare with val3, fail</span>
<span class="source-line-no">1992</span><span id="line-1992"> res = region.checkAndMutate(row1, fam1, qf1, CompareOperator.GREATER,</span>
<span class="source-line-no">1993</span><span id="line-1993"> new BinaryComparator(val3), put);</span>
<span class="source-line-no">1994</span><span id="line-1994"> assertEquals(false, res);</span>
<span class="source-line-no">1995</span><span id="line-1995"></span>
<span class="source-line-no">1996</span><span id="line-1996"> // Test CompareOp.GREATER: original = val3, compare with val2, fail</span>
<span class="source-line-no">1997</span><span id="line-1997"> res = region.checkAndMutate(row1, fam1, qf1, CompareOperator.GREATER,</span>
<span class="source-line-no">1998</span><span id="line-1998"> new BinaryComparator(val2), put);</span>
<span class="source-line-no">1999</span><span id="line-1999"> assertEquals(false, res);</span>
<span class="source-line-no">2000</span><span id="line-2000"></span>
<span class="source-line-no">2001</span><span id="line-2001"> // Test CompareOp.GREATER: original = val3, compare with val4,</span>
<span class="source-line-no">2002</span><span id="line-2002"> // succeed (now value = val2)</span>
<span class="source-line-no">2003</span><span id="line-2003"> put = new Put(row1);</span>
<span class="source-line-no">2004</span><span id="line-2004"> put.addColumn(fam1, qf1, val2);</span>
<span class="source-line-no">2005</span><span id="line-2005"> res = region.checkAndMutate(row1, fam1, qf1, CompareOperator.GREATER,</span>
<span class="source-line-no">2006</span><span id="line-2006"> new BinaryComparator(val4), put);</span>
<span class="source-line-no">2007</span><span id="line-2007"> assertEquals(true, res);</span>
<span class="source-line-no">2008</span><span id="line-2008"></span>
<span class="source-line-no">2009</span><span id="line-2009"> // Test CompareOp.GREATER_OR_EQUAL: original = val2, compare with val1, fail</span>
<span class="source-line-no">2010</span><span id="line-2010"> res = region.checkAndMutate(row1, fam1, qf1, CompareOperator.GREATER_OR_EQUAL,</span>
<span class="source-line-no">2011</span><span id="line-2011"> new BinaryComparator(val1), put);</span>
<span class="source-line-no">2012</span><span id="line-2012"> assertEquals(false, res);</span>
<span class="source-line-no">2013</span><span id="line-2013"></span>
<span class="source-line-no">2014</span><span id="line-2014"> // Test CompareOp.GREATER_OR_EQUAL: original = val2, compare with val2,</span>
<span class="source-line-no">2015</span><span id="line-2015"> // succeed (value still = val2)</span>
<span class="source-line-no">2016</span><span id="line-2016"> res = region.checkAndMutate(row1, fam1, qf1, CompareOperator.GREATER_OR_EQUAL,</span>
<span class="source-line-no">2017</span><span id="line-2017"> new BinaryComparator(val2), put);</span>
<span class="source-line-no">2018</span><span id="line-2018"> assertEquals(true, res);</span>
<span class="source-line-no">2019</span><span id="line-2019"></span>
<span class="source-line-no">2020</span><span id="line-2020"> // Test CompareOp.GREATER_OR_EQUAL: original = val2, compare with val3, succeed</span>
<span class="source-line-no">2021</span><span id="line-2021"> res = region.checkAndMutate(row1, fam1, qf1, CompareOperator.GREATER_OR_EQUAL,</span>
<span class="source-line-no">2022</span><span id="line-2022"> new BinaryComparator(val3), put);</span>
<span class="source-line-no">2023</span><span id="line-2023"> assertEquals(true, res);</span>
<span class="source-line-no">2024</span><span id="line-2024"> }</span>
<span class="source-line-no">2025</span><span id="line-2025"></span>
<span class="source-line-no">2026</span><span id="line-2026"> @Test</span>
<span class="source-line-no">2027</span><span id="line-2027"> @Deprecated</span>
<span class="source-line-no">2028</span><span id="line-2028"> public void testCheckAndPut_ThatPutWasWritten() throws IOException {</span>
<span class="source-line-no">2029</span><span id="line-2029"> byte[] row1 = Bytes.toBytes("row1");</span>
<span class="source-line-no">2030</span><span id="line-2030"> byte[] fam1 = Bytes.toBytes("fam1");</span>
<span class="source-line-no">2031</span><span id="line-2031"> byte[] fam2 = Bytes.toBytes("fam2");</span>
<span class="source-line-no">2032</span><span id="line-2032"> byte[] qf1 = Bytes.toBytes("qualifier");</span>
<span class="source-line-no">2033</span><span id="line-2033"> byte[] val1 = Bytes.toBytes("value1");</span>
<span class="source-line-no">2034</span><span id="line-2034"> byte[] val2 = Bytes.toBytes("value2");</span>
<span class="source-line-no">2035</span><span id="line-2035"></span>
<span class="source-line-no">2036</span><span id="line-2036"> byte[][] families = { fam1, fam2 };</span>
<span class="source-line-no">2037</span><span id="line-2037"></span>
<span class="source-line-no">2038</span><span id="line-2038"> // Setting up region</span>
<span class="source-line-no">2039</span><span id="line-2039"> this.region = initHRegion(tableName, method, CONF, families);</span>
<span class="source-line-no">2040</span><span id="line-2040"> // Putting data in the key to check</span>
<span class="source-line-no">2041</span><span id="line-2041"> Put put = new Put(row1);</span>
<span class="source-line-no">2042</span><span id="line-2042"> put.addColumn(fam1, qf1, val1);</span>
<span class="source-line-no">2043</span><span id="line-2043"> region.put(put);</span>
<span class="source-line-no">2044</span><span id="line-2044"></span>
<span class="source-line-no">2045</span><span id="line-2045"> // Creating put to add</span>
<span class="source-line-no">2046</span><span id="line-2046"> long ts = EnvironmentEdgeManager.currentTime();</span>
<span class="source-line-no">2047</span><span id="line-2047"> KeyValue kv = new KeyValue(row1, fam2, qf1, ts, KeyValue.Type.Put, val2);</span>
<span class="source-line-no">2048</span><span id="line-2048"> put = new Put(row1);</span>
<span class="source-line-no">2049</span><span id="line-2049"> put.add(kv);</span>
<span class="source-line-no">2050</span><span id="line-2050"></span>
<span class="source-line-no">2051</span><span id="line-2051"> // checkAndPut with wrong value</span>
<span class="source-line-no">2052</span><span id="line-2052"> boolean res = region.checkAndMutate(row1, fam1, qf1, CompareOperator.EQUAL,</span>
<span class="source-line-no">2053</span><span id="line-2053"> new BinaryComparator(val1), put);</span>
<span class="source-line-no">2054</span><span id="line-2054"> assertEquals(true, res);</span>
<span class="source-line-no">2055</span><span id="line-2055"></span>
<span class="source-line-no">2056</span><span id="line-2056"> Get get = new Get(row1);</span>
<span class="source-line-no">2057</span><span id="line-2057"> get.addColumn(fam2, qf1);</span>
<span class="source-line-no">2058</span><span id="line-2058"> Cell[] actual = region.get(get).rawCells();</span>
<span class="source-line-no">2059</span><span id="line-2059"></span>
<span class="source-line-no">2060</span><span id="line-2060"> Cell[] expected = { kv };</span>
<span class="source-line-no">2061</span><span id="line-2061"></span>
<span class="source-line-no">2062</span><span id="line-2062"> assertEquals(expected.length, actual.length);</span>
<span class="source-line-no">2063</span><span id="line-2063"> for (int i = 0; i &lt; actual.length; i++) {</span>
<span class="source-line-no">2064</span><span id="line-2064"> assertEquals(expected[i], actual[i]);</span>
<span class="source-line-no">2065</span><span id="line-2065"> }</span>
<span class="source-line-no">2066</span><span id="line-2066"> }</span>
<span class="source-line-no">2067</span><span id="line-2067"></span>
<span class="source-line-no">2068</span><span id="line-2068"> @Test</span>
<span class="source-line-no">2069</span><span id="line-2069"> @Deprecated</span>
<span class="source-line-no">2070</span><span id="line-2070"> public void testCheckAndPut_wrongRowInPut() throws IOException {</span>
<span class="source-line-no">2071</span><span id="line-2071"> this.region = initHRegion(tableName, method, CONF, COLUMNS);</span>
<span class="source-line-no">2072</span><span id="line-2072"> Put put = new Put(row2);</span>
<span class="source-line-no">2073</span><span id="line-2073"> put.addColumn(fam1, qual1, value1);</span>
<span class="source-line-no">2074</span><span id="line-2074"> try {</span>
<span class="source-line-no">2075</span><span id="line-2075"> region.checkAndMutate(row, fam1, qual1, CompareOperator.EQUAL, new BinaryComparator(value2),</span>
<span class="source-line-no">2076</span><span id="line-2076"> put);</span>
<span class="source-line-no">2077</span><span id="line-2077"> fail();</span>
<span class="source-line-no">2078</span><span id="line-2078"> } catch (org.apache.hadoop.hbase.DoNotRetryIOException expected) {</span>
<span class="source-line-no">2079</span><span id="line-2079"> // expected exception.</span>
<span class="source-line-no">2080</span><span id="line-2080"> }</span>
<span class="source-line-no">2081</span><span id="line-2081"> }</span>
<span class="source-line-no">2082</span><span id="line-2082"></span>
<span class="source-line-no">2083</span><span id="line-2083"> @Test</span>
<span class="source-line-no">2084</span><span id="line-2084"> @Deprecated</span>
<span class="source-line-no">2085</span><span id="line-2085"> public void testCheckAndDelete_ThatDeleteWasWritten() throws IOException {</span>
<span class="source-line-no">2086</span><span id="line-2086"> byte[] row1 = Bytes.toBytes("row1");</span>
<span class="source-line-no">2087</span><span id="line-2087"> byte[] fam1 = Bytes.toBytes("fam1");</span>
<span class="source-line-no">2088</span><span id="line-2088"> byte[] fam2 = Bytes.toBytes("fam2");</span>
<span class="source-line-no">2089</span><span id="line-2089"> byte[] qf1 = Bytes.toBytes("qualifier1");</span>
<span class="source-line-no">2090</span><span id="line-2090"> byte[] qf2 = Bytes.toBytes("qualifier2");</span>
<span class="source-line-no">2091</span><span id="line-2091"> byte[] qf3 = Bytes.toBytes("qualifier3");</span>
<span class="source-line-no">2092</span><span id="line-2092"> byte[] val1 = Bytes.toBytes("value1");</span>
<span class="source-line-no">2093</span><span id="line-2093"> byte[] val2 = Bytes.toBytes("value2");</span>
<span class="source-line-no">2094</span><span id="line-2094"> byte[] val3 = Bytes.toBytes("value3");</span>
<span class="source-line-no">2095</span><span id="line-2095"> byte[] emptyVal = new byte[] {};</span>
<span class="source-line-no">2096</span><span id="line-2096"></span>
<span class="source-line-no">2097</span><span id="line-2097"> byte[][] families = { fam1, fam2 };</span>
<span class="source-line-no">2098</span><span id="line-2098"></span>
<span class="source-line-no">2099</span><span id="line-2099"> // Setting up region</span>
<span class="source-line-no">2100</span><span id="line-2100"> this.region = initHRegion(tableName, method, CONF, families);</span>
<span class="source-line-no">2101</span><span id="line-2101"> // Put content</span>
<span class="source-line-no">2102</span><span id="line-2102"> Put put = new Put(row1);</span>
<span class="source-line-no">2103</span><span id="line-2103"> put.addColumn(fam1, qf1, val1);</span>
<span class="source-line-no">2104</span><span id="line-2104"> region.put(put);</span>
<span class="source-line-no">2105</span><span id="line-2105"> Threads.sleep(2);</span>
<span class="source-line-no">2106</span><span id="line-2106"></span>
<span class="source-line-no">2107</span><span id="line-2107"> put = new Put(row1);</span>
<span class="source-line-no">2108</span><span id="line-2108"> put.addColumn(fam1, qf1, val2);</span>
<span class="source-line-no">2109</span><span id="line-2109"> put.addColumn(fam2, qf1, val3);</span>
<span class="source-line-no">2110</span><span id="line-2110"> put.addColumn(fam2, qf2, val2);</span>
<span class="source-line-no">2111</span><span id="line-2111"> put.addColumn(fam2, qf3, val1);</span>
<span class="source-line-no">2112</span><span id="line-2112"> put.addColumn(fam1, qf3, val1);</span>
<span class="source-line-no">2113</span><span id="line-2113"> region.put(put);</span>
<span class="source-line-no">2114</span><span id="line-2114"></span>
<span class="source-line-no">2115</span><span id="line-2115"> LOG.info("get={}", region.get(new Get(row1).addColumn(fam1, qf1)).toString());</span>
<span class="source-line-no">2116</span><span id="line-2116"></span>
<span class="source-line-no">2117</span><span id="line-2117"> // Multi-column delete</span>
<span class="source-line-no">2118</span><span id="line-2118"> Delete delete = new Delete(row1);</span>
<span class="source-line-no">2119</span><span id="line-2119"> delete.addColumn(fam1, qf1);</span>
<span class="source-line-no">2120</span><span id="line-2120"> delete.addColumn(fam2, qf1);</span>
<span class="source-line-no">2121</span><span id="line-2121"> delete.addColumn(fam1, qf3);</span>
<span class="source-line-no">2122</span><span id="line-2122"> boolean res = region.checkAndMutate(row1, fam1, qf1, CompareOperator.EQUAL,</span>
<span class="source-line-no">2123</span><span id="line-2123"> new BinaryComparator(val2), delete);</span>
<span class="source-line-no">2124</span><span id="line-2124"> assertEquals(true, res);</span>
<span class="source-line-no">2125</span><span id="line-2125"></span>
<span class="source-line-no">2126</span><span id="line-2126"> Get get = new Get(row1);</span>
<span class="source-line-no">2127</span><span id="line-2127"> get.addColumn(fam1, qf1);</span>
<span class="source-line-no">2128</span><span id="line-2128"> get.addColumn(fam1, qf3);</span>
<span class="source-line-no">2129</span><span id="line-2129"> get.addColumn(fam2, qf2);</span>
<span class="source-line-no">2130</span><span id="line-2130"> Result r = region.get(get);</span>
<span class="source-line-no">2131</span><span id="line-2131"> assertEquals(2, r.size());</span>
<span class="source-line-no">2132</span><span id="line-2132"> assertArrayEquals(val1, r.getValue(fam1, qf1));</span>
<span class="source-line-no">2133</span><span id="line-2133"> assertArrayEquals(val2, r.getValue(fam2, qf2));</span>
<span class="source-line-no">2134</span><span id="line-2134"></span>
<span class="source-line-no">2135</span><span id="line-2135"> // Family delete</span>
<span class="source-line-no">2136</span><span id="line-2136"> delete = new Delete(row1);</span>
<span class="source-line-no">2137</span><span id="line-2137"> delete.addFamily(fam2);</span>
<span class="source-line-no">2138</span><span id="line-2138"> res = region.checkAndMutate(row1, fam2, qf1, CompareOperator.EQUAL,</span>
<span class="source-line-no">2139</span><span id="line-2139"> new BinaryComparator(emptyVal), delete);</span>
<span class="source-line-no">2140</span><span id="line-2140"> assertEquals(true, res);</span>
<span class="source-line-no">2141</span><span id="line-2141"></span>
<span class="source-line-no">2142</span><span id="line-2142"> get = new Get(row1);</span>
<span class="source-line-no">2143</span><span id="line-2143"> r = region.get(get);</span>
<span class="source-line-no">2144</span><span id="line-2144"> assertEquals(1, r.size());</span>
<span class="source-line-no">2145</span><span id="line-2145"> assertArrayEquals(val1, r.getValue(fam1, qf1));</span>
<span class="source-line-no">2146</span><span id="line-2146"></span>
<span class="source-line-no">2147</span><span id="line-2147"> // Row delete</span>
<span class="source-line-no">2148</span><span id="line-2148"> delete = new Delete(row1);</span>
<span class="source-line-no">2149</span><span id="line-2149"> res = region.checkAndMutate(row1, fam1, qf1, CompareOperator.EQUAL, new BinaryComparator(val1),</span>
<span class="source-line-no">2150</span><span id="line-2150"> delete);</span>
<span class="source-line-no">2151</span><span id="line-2151"> assertEquals(true, res);</span>
<span class="source-line-no">2152</span><span id="line-2152"> get = new Get(row1);</span>
<span class="source-line-no">2153</span><span id="line-2153"> r = region.get(get);</span>
<span class="source-line-no">2154</span><span id="line-2154"> assertEquals(0, r.size());</span>
<span class="source-line-no">2155</span><span id="line-2155"> }</span>
<span class="source-line-no">2156</span><span id="line-2156"></span>
<span class="source-line-no">2157</span><span id="line-2157"> @Test</span>
<span class="source-line-no">2158</span><span id="line-2158"> @Deprecated</span>
<span class="source-line-no">2159</span><span id="line-2159"> public void testCheckAndMutate_WithFilters() throws Throwable {</span>
<span class="source-line-no">2160</span><span id="line-2160"> final byte[] FAMILY = Bytes.toBytes("fam");</span>
<span class="source-line-no">2161</span><span id="line-2161"></span>
<span class="source-line-no">2162</span><span id="line-2162"> // Setting up region</span>
<span class="source-line-no">2163</span><span id="line-2163"> this.region = initHRegion(tableName, method, CONF, FAMILY);</span>
<span class="source-line-no">2164</span><span id="line-2164"></span>
<span class="source-line-no">2165</span><span id="line-2165"> // Put one row</span>
<span class="source-line-no">2166</span><span id="line-2166"> Put put = new Put(row);</span>
<span class="source-line-no">2167</span><span id="line-2167"> put.addColumn(FAMILY, Bytes.toBytes("A"), Bytes.toBytes("a"));</span>
<span class="source-line-no">2168</span><span id="line-2168"> put.addColumn(FAMILY, Bytes.toBytes("B"), Bytes.toBytes("b"));</span>
<span class="source-line-no">2169</span><span id="line-2169"> put.addColumn(FAMILY, Bytes.toBytes("C"), Bytes.toBytes("c"));</span>
<span class="source-line-no">2170</span><span id="line-2170"> region.put(put);</span>
<span class="source-line-no">2171</span><span id="line-2171"></span>
<span class="source-line-no">2172</span><span id="line-2172"> // Put with success</span>
<span class="source-line-no">2173</span><span id="line-2173"> boolean ok = region.checkAndMutate(row,</span>
<span class="source-line-no">2174</span><span id="line-2174"> new FilterList(</span>
<span class="source-line-no">2175</span><span id="line-2175"> new SingleColumnValueFilter(FAMILY, Bytes.toBytes("A"), CompareOperator.EQUAL,</span>
<span class="source-line-no">2176</span><span id="line-2176"> Bytes.toBytes("a")),</span>
<span class="source-line-no">2177</span><span id="line-2177"> new SingleColumnValueFilter(FAMILY, Bytes.toBytes("B"), CompareOperator.EQUAL,</span>
<span class="source-line-no">2178</span><span id="line-2178"> Bytes.toBytes("b"))),</span>
<span class="source-line-no">2179</span><span id="line-2179"> new Put(row).addColumn(FAMILY, Bytes.toBytes("D"), Bytes.toBytes("d")));</span>
<span class="source-line-no">2180</span><span id="line-2180"> assertTrue(ok);</span>
<span class="source-line-no">2181</span><span id="line-2181"></span>
<span class="source-line-no">2182</span><span id="line-2182"> Result result = region.get(new Get(row).addColumn(FAMILY, Bytes.toBytes("D")));</span>
<span class="source-line-no">2183</span><span id="line-2183"> assertEquals("d", Bytes.toString(result.getValue(FAMILY, Bytes.toBytes("D"))));</span>
<span class="source-line-no">2184</span><span id="line-2184"></span>
<span class="source-line-no">2185</span><span id="line-2185"> // Put with failure</span>
<span class="source-line-no">2186</span><span id="line-2186"> ok = region.checkAndMutate(row,</span>
<span class="source-line-no">2187</span><span id="line-2187"> new FilterList(</span>
<span class="source-line-no">2188</span><span id="line-2188"> new SingleColumnValueFilter(FAMILY, Bytes.toBytes("A"), CompareOperator.EQUAL,</span>
<span class="source-line-no">2189</span><span id="line-2189"> Bytes.toBytes("a")),</span>
<span class="source-line-no">2190</span><span id="line-2190"> new SingleColumnValueFilter(FAMILY, Bytes.toBytes("B"), CompareOperator.EQUAL,</span>
<span class="source-line-no">2191</span><span id="line-2191"> Bytes.toBytes("c"))),</span>
<span class="source-line-no">2192</span><span id="line-2192"> new Put(row).addColumn(FAMILY, Bytes.toBytes("E"), Bytes.toBytes("e")));</span>
<span class="source-line-no">2193</span><span id="line-2193"> assertFalse(ok);</span>
<span class="source-line-no">2194</span><span id="line-2194"></span>
<span class="source-line-no">2195</span><span id="line-2195"> assertTrue(region.get(new Get(row).addColumn(FAMILY, Bytes.toBytes("E"))).isEmpty());</span>
<span class="source-line-no">2196</span><span id="line-2196"></span>
<span class="source-line-no">2197</span><span id="line-2197"> // Delete with success</span>
<span class="source-line-no">2198</span><span id="line-2198"> ok = region.checkAndMutate(row,</span>
<span class="source-line-no">2199</span><span id="line-2199"> new FilterList(</span>
<span class="source-line-no">2200</span><span id="line-2200"> new SingleColumnValueFilter(FAMILY, Bytes.toBytes("A"), CompareOperator.EQUAL,</span>
<span class="source-line-no">2201</span><span id="line-2201"> Bytes.toBytes("a")),</span>
<span class="source-line-no">2202</span><span id="line-2202"> new SingleColumnValueFilter(FAMILY, Bytes.toBytes("B"), CompareOperator.EQUAL,</span>
<span class="source-line-no">2203</span><span id="line-2203"> Bytes.toBytes("b"))),</span>
<span class="source-line-no">2204</span><span id="line-2204"> new Delete(row).addColumns(FAMILY, Bytes.toBytes("D")));</span>
<span class="source-line-no">2205</span><span id="line-2205"> assertTrue(ok);</span>
<span class="source-line-no">2206</span><span id="line-2206"></span>
<span class="source-line-no">2207</span><span id="line-2207"> assertTrue(region.get(new Get(row).addColumn(FAMILY, Bytes.toBytes("D"))).isEmpty());</span>
<span class="source-line-no">2208</span><span id="line-2208"></span>
<span class="source-line-no">2209</span><span id="line-2209"> // Mutate with success</span>
<span class="source-line-no">2210</span><span id="line-2210"> ok = region.checkAndRowMutate(row,</span>
<span class="source-line-no">2211</span><span id="line-2211"> new FilterList(</span>
<span class="source-line-no">2212</span><span id="line-2212"> new SingleColumnValueFilter(FAMILY, Bytes.toBytes("A"), CompareOperator.EQUAL,</span>
<span class="source-line-no">2213</span><span id="line-2213"> Bytes.toBytes("a")),</span>
<span class="source-line-no">2214</span><span id="line-2214"> new SingleColumnValueFilter(FAMILY, Bytes.toBytes("B"), CompareOperator.EQUAL,</span>
<span class="source-line-no">2215</span><span id="line-2215"> Bytes.toBytes("b"))),</span>
<span class="source-line-no">2216</span><span id="line-2216"> new RowMutations(row)</span>
<span class="source-line-no">2217</span><span id="line-2217"> .add((Mutation) new Put(row).addColumn(FAMILY, Bytes.toBytes("E"), Bytes.toBytes("e")))</span>
<span class="source-line-no">2218</span><span id="line-2218"> .add((Mutation) new Delete(row).addColumns(FAMILY, Bytes.toBytes("A"))));</span>
<span class="source-line-no">2219</span><span id="line-2219"> assertTrue(ok);</span>
<span class="source-line-no">2220</span><span id="line-2220"></span>
<span class="source-line-no">2221</span><span id="line-2221"> result = region.get(new Get(row).addColumn(FAMILY, Bytes.toBytes("E")));</span>
<span class="source-line-no">2222</span><span id="line-2222"> assertEquals("e", Bytes.toString(result.getValue(FAMILY, Bytes.toBytes("E"))));</span>
<span class="source-line-no">2223</span><span id="line-2223"></span>
<span class="source-line-no">2224</span><span id="line-2224"> assertTrue(region.get(new Get(row).addColumn(FAMILY, Bytes.toBytes("A"))).isEmpty());</span>
<span class="source-line-no">2225</span><span id="line-2225"> }</span>
<span class="source-line-no">2226</span><span id="line-2226"></span>
<span class="source-line-no">2227</span><span id="line-2227"> @Test</span>
<span class="source-line-no">2228</span><span id="line-2228"> @Deprecated</span>
<span class="source-line-no">2229</span><span id="line-2229"> public void testCheckAndMutate_WithFiltersAndTimeRange() throws Throwable {</span>
<span class="source-line-no">2230</span><span id="line-2230"> final byte[] FAMILY = Bytes.toBytes("fam");</span>
<span class="source-line-no">2231</span><span id="line-2231"></span>
<span class="source-line-no">2232</span><span id="line-2232"> // Setting up region</span>
<span class="source-line-no">2233</span><span id="line-2233"> this.region = initHRegion(tableName, method, CONF, FAMILY);</span>
<span class="source-line-no">2234</span><span id="line-2234"></span>
<span class="source-line-no">2235</span><span id="line-2235"> // Put with specifying the timestamp</span>
<span class="source-line-no">2236</span><span id="line-2236"> region.put(new Put(row).addColumn(FAMILY, Bytes.toBytes("A"), 100, Bytes.toBytes("a")));</span>
<span class="source-line-no">2237</span><span id="line-2237"></span>
<span class="source-line-no">2238</span><span id="line-2238"> // Put with success</span>
<span class="source-line-no">2239</span><span id="line-2239"> boolean ok = region.checkAndMutate(row,</span>
<span class="source-line-no">2240</span><span id="line-2240"> new SingleColumnValueFilter(FAMILY, Bytes.toBytes("A"), CompareOperator.EQUAL,</span>
<span class="source-line-no">2241</span><span id="line-2241"> Bytes.toBytes("a")),</span>
<span class="source-line-no">2242</span><span id="line-2242"> TimeRange.between(0, 101),</span>
<span class="source-line-no">2243</span><span id="line-2243"> new Put(row).addColumn(FAMILY, Bytes.toBytes("B"), Bytes.toBytes("b")));</span>
<span class="source-line-no">2244</span><span id="line-2244"> assertTrue(ok);</span>
<span class="source-line-no">2245</span><span id="line-2245"></span>
<span class="source-line-no">2246</span><span id="line-2246"> Result result = region.get(new Get(row).addColumn(FAMILY, Bytes.toBytes("B")));</span>
<span class="source-line-no">2247</span><span id="line-2247"> assertEquals("b", Bytes.toString(result.getValue(FAMILY, Bytes.toBytes("B"))));</span>
<span class="source-line-no">2248</span><span id="line-2248"></span>
<span class="source-line-no">2249</span><span id="line-2249"> // Put with failure</span>
<span class="source-line-no">2250</span><span id="line-2250"> ok = region.checkAndMutate(row,</span>
<span class="source-line-no">2251</span><span id="line-2251"> new SingleColumnValueFilter(FAMILY, Bytes.toBytes("A"), CompareOperator.EQUAL,</span>
<span class="source-line-no">2252</span><span id="line-2252"> Bytes.toBytes("a")),</span>
<span class="source-line-no">2253</span><span id="line-2253"> TimeRange.between(0, 100),</span>
<span class="source-line-no">2254</span><span id="line-2254"> new Put(row).addColumn(FAMILY, Bytes.toBytes("C"), Bytes.toBytes("c")));</span>
<span class="source-line-no">2255</span><span id="line-2255"> assertFalse(ok);</span>
<span class="source-line-no">2256</span><span id="line-2256"></span>
<span class="source-line-no">2257</span><span id="line-2257"> assertTrue(region.get(new Get(row).addColumn(FAMILY, Bytes.toBytes("C"))).isEmpty());</span>
<span class="source-line-no">2258</span><span id="line-2258"></span>
<span class="source-line-no">2259</span><span id="line-2259"> // Mutate with success</span>
<span class="source-line-no">2260</span><span id="line-2260"> ok = region.checkAndRowMutate(row,</span>
<span class="source-line-no">2261</span><span id="line-2261"> new SingleColumnValueFilter(</span>
<span class="source-line-no">2262</span><span id="line-2262"> FAMILY, Bytes.toBytes("A"), CompareOperator.EQUAL, Bytes.toBytes("a")),</span>
<span class="source-line-no">2263</span><span id="line-2263"> TimeRange.between(0, 101),</span>
<span class="source-line-no">2264</span><span id="line-2264"> new RowMutations(row)</span>
<span class="source-line-no">2265</span><span id="line-2265"> .add((Mutation) new Put(row).addColumn(FAMILY, Bytes.toBytes("D"), Bytes.toBytes("d")))</span>
<span class="source-line-no">2266</span><span id="line-2266"> .add((Mutation) new Delete(row).addColumns(FAMILY, Bytes.toBytes("A"))));</span>
<span class="source-line-no">2267</span><span id="line-2267"> assertTrue(ok);</span>
<span class="source-line-no">2268</span><span id="line-2268"></span>
<span class="source-line-no">2269</span><span id="line-2269"> result = region.get(new Get(row).addColumn(FAMILY, Bytes.toBytes("D")));</span>
<span class="source-line-no">2270</span><span id="line-2270"> assertEquals("d", Bytes.toString(result.getValue(FAMILY, Bytes.toBytes("D"))));</span>
<span class="source-line-no">2271</span><span id="line-2271"></span>
<span class="source-line-no">2272</span><span id="line-2272"> assertTrue(region.get(new Get(row).addColumn(FAMILY, Bytes.toBytes("A"))).isEmpty());</span>
<span class="source-line-no">2273</span><span id="line-2273"> }</span>
<span class="source-line-no">2274</span><span id="line-2274"></span>
<span class="source-line-no">2275</span><span id="line-2275"> @Test</span>
<span class="source-line-no">2276</span><span id="line-2276"> @Deprecated</span>
<span class="source-line-no">2277</span><span id="line-2277"> public void testCheckAndMutate_wrongMutationType() throws Throwable {</span>
<span class="source-line-no">2278</span><span id="line-2278"> // Setting up region</span>
<span class="source-line-no">2279</span><span id="line-2279"> this.region = initHRegion(tableName, method, CONF, fam1);</span>
<span class="source-line-no">2280</span><span id="line-2280"></span>
<span class="source-line-no">2281</span><span id="line-2281"> try {</span>
<span class="source-line-no">2282</span><span id="line-2282"> region.checkAndMutate(row, fam1, qual1, CompareOperator.EQUAL, new BinaryComparator(value1),</span>
<span class="source-line-no">2283</span><span id="line-2283"> new Increment(row).addColumn(fam1, qual1, 1));</span>
<span class="source-line-no">2284</span><span id="line-2284"> fail("should throw DoNotRetryIOException");</span>
<span class="source-line-no">2285</span><span id="line-2285"> } catch (DoNotRetryIOException e) {</span>
<span class="source-line-no">2286</span><span id="line-2286"> assertEquals("Unsupported mutate type: INCREMENT", e.getMessage());</span>
<span class="source-line-no">2287</span><span id="line-2287"> }</span>
<span class="source-line-no">2288</span><span id="line-2288"></span>
<span class="source-line-no">2289</span><span id="line-2289"> try {</span>
<span class="source-line-no">2290</span><span id="line-2290"> region.checkAndMutate(row,</span>
<span class="source-line-no">2291</span><span id="line-2291"> new SingleColumnValueFilter(fam1, qual1, CompareOperator.EQUAL, value1),</span>
<span class="source-line-no">2292</span><span id="line-2292"> new Increment(row).addColumn(fam1, qual1, 1));</span>
<span class="source-line-no">2293</span><span id="line-2293"> fail("should throw DoNotRetryIOException");</span>
<span class="source-line-no">2294</span><span id="line-2294"> } catch (DoNotRetryIOException e) {</span>
<span class="source-line-no">2295</span><span id="line-2295"> assertEquals("Unsupported mutate type: INCREMENT", e.getMessage());</span>
<span class="source-line-no">2296</span><span id="line-2296"> }</span>
<span class="source-line-no">2297</span><span id="line-2297"> }</span>
<span class="source-line-no">2298</span><span id="line-2298"></span>
<span class="source-line-no">2299</span><span id="line-2299"> @Test</span>
<span class="source-line-no">2300</span><span id="line-2300"> @Deprecated</span>
<span class="source-line-no">2301</span><span id="line-2301"> public void testCheckAndMutate_wrongRow() throws Throwable {</span>
<span class="source-line-no">2302</span><span id="line-2302"> final byte[] wrongRow = Bytes.toBytes("wrongRow");</span>
<span class="source-line-no">2303</span><span id="line-2303"></span>
<span class="source-line-no">2304</span><span id="line-2304"> // Setting up region</span>
<span class="source-line-no">2305</span><span id="line-2305"> this.region = initHRegion(tableName, method, CONF, fam1);</span>
<span class="source-line-no">2306</span><span id="line-2306"></span>
<span class="source-line-no">2307</span><span id="line-2307"> try {</span>
<span class="source-line-no">2308</span><span id="line-2308"> region.checkAndMutate(row, fam1, qual1, CompareOperator.EQUAL, new BinaryComparator(value1),</span>
<span class="source-line-no">2309</span><span id="line-2309"> new Put(wrongRow).addColumn(fam1, qual1, value1));</span>
<span class="source-line-no">2310</span><span id="line-2310"> fail("should throw DoNotRetryIOException");</span>
<span class="source-line-no">2311</span><span id="line-2311"> } catch (DoNotRetryIOException e) {</span>
<span class="source-line-no">2312</span><span id="line-2312"> assertEquals("The row of the action &lt;wrongRow&gt; doesn't match the original one &lt;rowA&gt;",</span>
<span class="source-line-no">2313</span><span id="line-2313"> e.getMessage());</span>
<span class="source-line-no">2314</span><span id="line-2314"> }</span>
<span class="source-line-no">2315</span><span id="line-2315"></span>
<span class="source-line-no">2316</span><span id="line-2316"> try {</span>
<span class="source-line-no">2317</span><span id="line-2317"> region.checkAndMutate(row,</span>
<span class="source-line-no">2318</span><span id="line-2318"> new SingleColumnValueFilter(fam1, qual1, CompareOperator.EQUAL, value1),</span>
<span class="source-line-no">2319</span><span id="line-2319"> new Put(wrongRow).addColumn(fam1, qual1, value1));</span>
<span class="source-line-no">2320</span><span id="line-2320"> fail("should throw DoNotRetryIOException");</span>
<span class="source-line-no">2321</span><span id="line-2321"> } catch (DoNotRetryIOException e) {</span>
<span class="source-line-no">2322</span><span id="line-2322"> assertEquals("The row of the action &lt;wrongRow&gt; doesn't match the original one &lt;rowA&gt;",</span>
<span class="source-line-no">2323</span><span id="line-2323"> e.getMessage());</span>
<span class="source-line-no">2324</span><span id="line-2324"> }</span>
<span class="source-line-no">2325</span><span id="line-2325"></span>
<span class="source-line-no">2326</span><span id="line-2326"> try {</span>
<span class="source-line-no">2327</span><span id="line-2327"> region.checkAndRowMutate(row, fam1, qual1, CompareOperator.EQUAL,</span>
<span class="source-line-no">2328</span><span id="line-2328"> new BinaryComparator(value1),</span>
<span class="source-line-no">2329</span><span id="line-2329"> new RowMutations(wrongRow).add((Mutation) new Put(wrongRow).addColumn(fam1, qual1, value1))</span>
<span class="source-line-no">2330</span><span id="line-2330"> .add((Mutation) new Delete(wrongRow).addColumns(fam1, qual2)));</span>
<span class="source-line-no">2331</span><span id="line-2331"> fail("should throw DoNotRetryIOException");</span>
<span class="source-line-no">2332</span><span id="line-2332"> } catch (DoNotRetryIOException e) {</span>
<span class="source-line-no">2333</span><span id="line-2333"> assertEquals("The row of the action &lt;wrongRow&gt; doesn't match the original one &lt;rowA&gt;",</span>
<span class="source-line-no">2334</span><span id="line-2334"> e.getMessage());</span>
<span class="source-line-no">2335</span><span id="line-2335"> }</span>
<span class="source-line-no">2336</span><span id="line-2336"></span>
<span class="source-line-no">2337</span><span id="line-2337"> try {</span>
<span class="source-line-no">2338</span><span id="line-2338"> region.checkAndRowMutate(row,</span>
<span class="source-line-no">2339</span><span id="line-2339"> new SingleColumnValueFilter(fam1, qual1, CompareOperator.EQUAL, value1),</span>
<span class="source-line-no">2340</span><span id="line-2340"> new RowMutations(wrongRow).add((Mutation) new Put(wrongRow).addColumn(fam1, qual1, value1))</span>
<span class="source-line-no">2341</span><span id="line-2341"> .add((Mutation) new Delete(wrongRow).addColumns(fam1, qual2)));</span>
<span class="source-line-no">2342</span><span id="line-2342"> fail("should throw DoNotRetryIOException");</span>
<span class="source-line-no">2343</span><span id="line-2343"> } catch (DoNotRetryIOException e) {</span>
<span class="source-line-no">2344</span><span id="line-2344"> assertEquals("The row of the action &lt;wrongRow&gt; doesn't match the original one &lt;rowA&gt;",</span>
<span class="source-line-no">2345</span><span id="line-2345"> e.getMessage());</span>
<span class="source-line-no">2346</span><span id="line-2346"> }</span>
<span class="source-line-no">2347</span><span id="line-2347"> }</span>
<span class="source-line-no">2348</span><span id="line-2348"></span>
<span class="source-line-no">2349</span><span id="line-2349"> @Test</span>
<span class="source-line-no">2350</span><span id="line-2350"> public void testCheckAndMutateWithEmptyRowValue() throws IOException {</span>
<span class="source-line-no">2351</span><span id="line-2351"> byte[] row1 = Bytes.toBytes("row1");</span>
<span class="source-line-no">2352</span><span id="line-2352"> byte[] fam1 = Bytes.toBytes("fam1");</span>
<span class="source-line-no">2353</span><span id="line-2353"> byte[] qf1 = Bytes.toBytes("qualifier");</span>
<span class="source-line-no">2354</span><span id="line-2354"> byte[] emptyVal = new byte[] {};</span>
<span class="source-line-no">2355</span><span id="line-2355"> byte[] val1 = Bytes.toBytes("value1");</span>
<span class="source-line-no">2356</span><span id="line-2356"> byte[] val2 = Bytes.toBytes("value2");</span>
<span class="source-line-no">2357</span><span id="line-2357"></span>
<span class="source-line-no">2358</span><span id="line-2358"> // Setting up region</span>
<span class="source-line-no">2359</span><span id="line-2359"> this.region = initHRegion(tableName, method, CONF, fam1);</span>
<span class="source-line-no">2360</span><span id="line-2360"> // Putting empty data in key</span>
<span class="source-line-no">2361</span><span id="line-2361"> Put put = new Put(row1);</span>
<span class="source-line-no">2362</span><span id="line-2362"> put.addColumn(fam1, qf1, emptyVal);</span>
<span class="source-line-no">2363</span><span id="line-2363"></span>
<span class="source-line-no">2364</span><span id="line-2364"> // checkAndPut with empty value</span>
<span class="source-line-no">2365</span><span id="line-2365"> CheckAndMutateResult res = region.checkAndMutate(CheckAndMutate.newBuilder(row1)</span>
<span class="source-line-no">2366</span><span id="line-2366"> .ifMatches(fam1, qf1, CompareOperator.EQUAL, emptyVal).build(put));</span>
<span class="source-line-no">2367</span><span id="line-2367"> assertTrue(res.isSuccess());</span>
<span class="source-line-no">2368</span><span id="line-2368"> assertNull(res.getResult());</span>
<span class="source-line-no">2369</span><span id="line-2369"></span>
<span class="source-line-no">2370</span><span id="line-2370"> // Putting data in key</span>
<span class="source-line-no">2371</span><span id="line-2371"> put = new Put(row1);</span>
<span class="source-line-no">2372</span><span id="line-2372"> put.addColumn(fam1, qf1, val1);</span>
<span class="source-line-no">2373</span><span id="line-2373"></span>
<span class="source-line-no">2374</span><span id="line-2374"> // checkAndPut with correct value</span>
<span class="source-line-no">2375</span><span id="line-2375"> res = region.checkAndMutate(CheckAndMutate.newBuilder(row1)</span>
<span class="source-line-no">2376</span><span id="line-2376"> .ifMatches(fam1, qf1, CompareOperator.EQUAL, emptyVal).build(put));</span>
<span class="source-line-no">2377</span><span id="line-2377"> assertTrue(res.isSuccess());</span>
<span class="source-line-no">2378</span><span id="line-2378"> assertNull(res.getResult());</span>
<span class="source-line-no">2379</span><span id="line-2379"></span>
<span class="source-line-no">2380</span><span id="line-2380"> // not empty anymore</span>
<span class="source-line-no">2381</span><span id="line-2381"> res = region.checkAndMutate(CheckAndMutate.newBuilder(row1)</span>
<span class="source-line-no">2382</span><span id="line-2382"> .ifMatches(fam1, qf1, CompareOperator.EQUAL, emptyVal).build(put));</span>
<span class="source-line-no">2383</span><span id="line-2383"> assertFalse(res.isSuccess());</span>
<span class="source-line-no">2384</span><span id="line-2384"> assertNull(res.getResult());</span>
<span class="source-line-no">2385</span><span id="line-2385"></span>
<span class="source-line-no">2386</span><span id="line-2386"> Delete delete = new Delete(row1);</span>
<span class="source-line-no">2387</span><span id="line-2387"> delete.addColumn(fam1, qf1);</span>
<span class="source-line-no">2388</span><span id="line-2388"> res = region.checkAndMutate(CheckAndMutate.newBuilder(row1)</span>
<span class="source-line-no">2389</span><span id="line-2389"> .ifMatches(fam1, qf1, CompareOperator.EQUAL, emptyVal).build(delete));</span>
<span class="source-line-no">2390</span><span id="line-2390"> assertFalse(res.isSuccess());</span>
<span class="source-line-no">2391</span><span id="line-2391"> assertNull(res.getResult());</span>
<span class="source-line-no">2392</span><span id="line-2392"></span>
<span class="source-line-no">2393</span><span id="line-2393"> put = new Put(row1);</span>
<span class="source-line-no">2394</span><span id="line-2394"> put.addColumn(fam1, qf1, val2);</span>
<span class="source-line-no">2395</span><span id="line-2395"> // checkAndPut with correct value</span>
<span class="source-line-no">2396</span><span id="line-2396"> res = region.checkAndMutate(</span>
<span class="source-line-no">2397</span><span id="line-2397"> CheckAndMutate.newBuilder(row1).ifMatches(fam1, qf1, CompareOperator.EQUAL, val1).build(put));</span>
<span class="source-line-no">2398</span><span id="line-2398"> assertTrue(res.isSuccess());</span>
<span class="source-line-no">2399</span><span id="line-2399"> assertNull(res.getResult());</span>
<span class="source-line-no">2400</span><span id="line-2400"></span>
<span class="source-line-no">2401</span><span id="line-2401"> // checkAndDelete with correct value</span>
<span class="source-line-no">2402</span><span id="line-2402"> delete = new Delete(row1);</span>
<span class="source-line-no">2403</span><span id="line-2403"> delete.addColumn(fam1, qf1);</span>
<span class="source-line-no">2404</span><span id="line-2404"> delete.addColumn(fam1, qf1);</span>
<span class="source-line-no">2405</span><span id="line-2405"> res = region.checkAndMutate(CheckAndMutate.newBuilder(row1)</span>
<span class="source-line-no">2406</span><span id="line-2406"> .ifMatches(fam1, qf1, CompareOperator.EQUAL, val2).build(delete));</span>
<span class="source-line-no">2407</span><span id="line-2407"> assertTrue(res.isSuccess());</span>
<span class="source-line-no">2408</span><span id="line-2408"> assertNull(res.getResult());</span>
<span class="source-line-no">2409</span><span id="line-2409"></span>
<span class="source-line-no">2410</span><span id="line-2410"> delete = new Delete(row1);</span>
<span class="source-line-no">2411</span><span id="line-2411"> res = region.checkAndMutate(CheckAndMutate.newBuilder(row1)</span>
<span class="source-line-no">2412</span><span id="line-2412"> .ifMatches(fam1, qf1, CompareOperator.EQUAL, emptyVal).build(delete));</span>
<span class="source-line-no">2413</span><span id="line-2413"> assertTrue(res.isSuccess());</span>
<span class="source-line-no">2414</span><span id="line-2414"> assertNull(res.getResult());</span>
<span class="source-line-no">2415</span><span id="line-2415"></span>
<span class="source-line-no">2416</span><span id="line-2416"> // checkAndPut looking for a null value</span>
<span class="source-line-no">2417</span><span id="line-2417"> put = new Put(row1);</span>
<span class="source-line-no">2418</span><span id="line-2418"> put.addColumn(fam1, qf1, val1);</span>
<span class="source-line-no">2419</span><span id="line-2419"></span>
<span class="source-line-no">2420</span><span id="line-2420"> res = region.checkAndMutate(CheckAndMutate.newBuilder(row1).ifNotExists(fam1, qf1).build(put));</span>
<span class="source-line-no">2421</span><span id="line-2421"> assertTrue(res.isSuccess());</span>
<span class="source-line-no">2422</span><span id="line-2422"> assertNull(res.getResult());</span>
<span class="source-line-no">2423</span><span id="line-2423"> }</span>
<span class="source-line-no">2424</span><span id="line-2424"></span>
<span class="source-line-no">2425</span><span id="line-2425"> @Test</span>
<span class="source-line-no">2426</span><span id="line-2426"> public void testCheckAndMutateWithWrongValue() throws IOException {</span>
<span class="source-line-no">2427</span><span id="line-2427"> byte[] row1 = Bytes.toBytes("row1");</span>
<span class="source-line-no">2428</span><span id="line-2428"> byte[] fam1 = Bytes.toBytes("fam1");</span>
<span class="source-line-no">2429</span><span id="line-2429"> byte[] qf1 = Bytes.toBytes("qualifier");</span>
<span class="source-line-no">2430</span><span id="line-2430"> byte[] val1 = Bytes.toBytes("value1");</span>
<span class="source-line-no">2431</span><span id="line-2431"> byte[] val2 = Bytes.toBytes("value2");</span>
<span class="source-line-no">2432</span><span id="line-2432"> BigDecimal bd1 = new BigDecimal(Double.MAX_VALUE);</span>
<span class="source-line-no">2433</span><span id="line-2433"> BigDecimal bd2 = new BigDecimal(Double.MIN_VALUE);</span>
<span class="source-line-no">2434</span><span id="line-2434"></span>
<span class="source-line-no">2435</span><span id="line-2435"> // Setting up region</span>
<span class="source-line-no">2436</span><span id="line-2436"> this.region = initHRegion(tableName, method, CONF, fam1);</span>
<span class="source-line-no">2437</span><span id="line-2437"> // Putting data in key</span>
<span class="source-line-no">2438</span><span id="line-2438"> Put put = new Put(row1);</span>
<span class="source-line-no">2439</span><span id="line-2439"> put.addColumn(fam1, qf1, val1);</span>
<span class="source-line-no">2440</span><span id="line-2440"> region.put(put);</span>
<span class="source-line-no">2441</span><span id="line-2441"></span>
<span class="source-line-no">2442</span><span id="line-2442"> // checkAndPut with wrong value</span>
<span class="source-line-no">2443</span><span id="line-2443"> CheckAndMutateResult res = region.checkAndMutate(</span>
<span class="source-line-no">2444</span><span id="line-2444"> CheckAndMutate.newBuilder(row1).ifMatches(fam1, qf1, CompareOperator.EQUAL, val2).build(put));</span>
<span class="source-line-no">2445</span><span id="line-2445"> assertFalse(res.isSuccess());</span>
<span class="source-line-no">2446</span><span id="line-2446"> assertNull(res.getResult());</span>
<span class="source-line-no">2447</span><span id="line-2447"></span>
<span class="source-line-no">2448</span><span id="line-2448"> // checkAndDelete with wrong value</span>
<span class="source-line-no">2449</span><span id="line-2449"> Delete delete = new Delete(row1);</span>
<span class="source-line-no">2450</span><span id="line-2450"> delete.addFamily(fam1);</span>
<span class="source-line-no">2451</span><span id="line-2451"> res = region.checkAndMutate(</span>
<span class="source-line-no">2452</span><span id="line-2452"> CheckAndMutate.newBuilder(row1).ifMatches(fam1, qf1, CompareOperator.EQUAL, val2).build(put));</span>
<span class="source-line-no">2453</span><span id="line-2453"> assertFalse(res.isSuccess());</span>
<span class="source-line-no">2454</span><span id="line-2454"> assertNull(res.getResult());</span>
<span class="source-line-no">2455</span><span id="line-2455"></span>
<span class="source-line-no">2456</span><span id="line-2456"> // Putting data in key</span>
<span class="source-line-no">2457</span><span id="line-2457"> put = new Put(row1);</span>
<span class="source-line-no">2458</span><span id="line-2458"> put.addColumn(fam1, qf1, Bytes.toBytes(bd1));</span>
<span class="source-line-no">2459</span><span id="line-2459"> region.put(put);</span>
<span class="source-line-no">2460</span><span id="line-2460"></span>
<span class="source-line-no">2461</span><span id="line-2461"> // checkAndPut with wrong value</span>
<span class="source-line-no">2462</span><span id="line-2462"> res = region.checkAndMutate(CheckAndMutate.newBuilder(row1)</span>
<span class="source-line-no">2463</span><span id="line-2463"> .ifMatches(fam1, qf1, CompareOperator.EQUAL, Bytes.toBytes(bd2)).build(put));</span>
<span class="source-line-no">2464</span><span id="line-2464"> assertFalse(res.isSuccess());</span>
<span class="source-line-no">2465</span><span id="line-2465"> assertNull(res.getResult());</span>
<span class="source-line-no">2466</span><span id="line-2466"></span>
<span class="source-line-no">2467</span><span id="line-2467"> // checkAndDelete with wrong value</span>
<span class="source-line-no">2468</span><span id="line-2468"> delete = new Delete(row1);</span>
<span class="source-line-no">2469</span><span id="line-2469"> delete.addFamily(fam1);</span>
<span class="source-line-no">2470</span><span id="line-2470"> res = region.checkAndMutate(CheckAndMutate.newBuilder(row1)</span>
<span class="source-line-no">2471</span><span id="line-2471"> .ifMatches(fam1, qf1, CompareOperator.EQUAL, Bytes.toBytes(bd2)).build(delete));</span>
<span class="source-line-no">2472</span><span id="line-2472"> assertFalse(res.isSuccess());</span>
<span class="source-line-no">2473</span><span id="line-2473"> assertNull(res.getResult());</span>
<span class="source-line-no">2474</span><span id="line-2474"> }</span>
<span class="source-line-no">2475</span><span id="line-2475"></span>
<span class="source-line-no">2476</span><span id="line-2476"> @Test</span>
<span class="source-line-no">2477</span><span id="line-2477"> public void testCheckAndMutateWithCorrectValue() throws IOException {</span>
<span class="source-line-no">2478</span><span id="line-2478"> byte[] row1 = Bytes.toBytes("row1");</span>
<span class="source-line-no">2479</span><span id="line-2479"> byte[] fam1 = Bytes.toBytes("fam1");</span>
<span class="source-line-no">2480</span><span id="line-2480"> byte[] qf1 = Bytes.toBytes("qualifier");</span>
<span class="source-line-no">2481</span><span id="line-2481"> byte[] val1 = Bytes.toBytes("value1");</span>
<span class="source-line-no">2482</span><span id="line-2482"> BigDecimal bd1 = new BigDecimal(Double.MIN_VALUE);</span>
<span class="source-line-no">2483</span><span id="line-2483"></span>
<span class="source-line-no">2484</span><span id="line-2484"> // Setting up region</span>
<span class="source-line-no">2485</span><span id="line-2485"> this.region = initHRegion(tableName, method, CONF, fam1);</span>
<span class="source-line-no">2486</span><span id="line-2486"> // Putting data in key</span>
<span class="source-line-no">2487</span><span id="line-2487"> long now = EnvironmentEdgeManager.currentTime();</span>
<span class="source-line-no">2488</span><span id="line-2488"> Put put = new Put(row1);</span>
<span class="source-line-no">2489</span><span id="line-2489"> put.addColumn(fam1, qf1, now, val1);</span>
<span class="source-line-no">2490</span><span id="line-2490"> region.put(put);</span>
<span class="source-line-no">2491</span><span id="line-2491"></span>
<span class="source-line-no">2492</span><span id="line-2492"> // checkAndPut with correct value</span>
<span class="source-line-no">2493</span><span id="line-2493"> CheckAndMutateResult res = region.checkAndMutate(</span>
<span class="source-line-no">2494</span><span id="line-2494"> CheckAndMutate.newBuilder(row1).ifMatches(fam1, qf1, CompareOperator.EQUAL, val1).build(put));</span>
<span class="source-line-no">2495</span><span id="line-2495"> assertTrue("First", res.isSuccess());</span>
<span class="source-line-no">2496</span><span id="line-2496"></span>
<span class="source-line-no">2497</span><span id="line-2497"> // checkAndDelete with correct value</span>
<span class="source-line-no">2498</span><span id="line-2498"> Delete delete = new Delete(row1, now + 1);</span>
<span class="source-line-no">2499</span><span id="line-2499"> delete.addColumn(fam1, qf1);</span>
<span class="source-line-no">2500</span><span id="line-2500"> res = region.checkAndMutate(CheckAndMutate.newBuilder(row1)</span>
<span class="source-line-no">2501</span><span id="line-2501"> .ifMatches(fam1, qf1, CompareOperator.EQUAL, val1).build(delete));</span>
<span class="source-line-no">2502</span><span id="line-2502"> assertTrue("Delete", res.isSuccess());</span>
<span class="source-line-no">2503</span><span id="line-2503"> assertNull(res.getResult());</span>
<span class="source-line-no">2504</span><span id="line-2504"></span>
<span class="source-line-no">2505</span><span id="line-2505"> // Putting data in key</span>
<span class="source-line-no">2506</span><span id="line-2506"> put = new Put(row1);</span>
<span class="source-line-no">2507</span><span id="line-2507"> put.addColumn(fam1, qf1, now + 2, Bytes.toBytes(bd1));</span>
<span class="source-line-no">2508</span><span id="line-2508"> region.put(put);</span>
<span class="source-line-no">2509</span><span id="line-2509"></span>
<span class="source-line-no">2510</span><span id="line-2510"> // checkAndPut with correct value</span>
<span class="source-line-no">2511</span><span id="line-2511"> res = region.checkAndMutate(CheckAndMutate.newBuilder(row1)</span>
<span class="source-line-no">2512</span><span id="line-2512"> .ifMatches(fam1, qf1, CompareOperator.EQUAL, Bytes.toBytes(bd1)).build(put));</span>
<span class="source-line-no">2513</span><span id="line-2513"> assertTrue("Second put", res.isSuccess());</span>
<span class="source-line-no">2514</span><span id="line-2514"> assertNull(res.getResult());</span>
<span class="source-line-no">2515</span><span id="line-2515"></span>
<span class="source-line-no">2516</span><span id="line-2516"> // checkAndDelete with correct value</span>
<span class="source-line-no">2517</span><span id="line-2517"> delete = new Delete(row1, now + 3);</span>
<span class="source-line-no">2518</span><span id="line-2518"> delete.addColumn(fam1, qf1);</span>
<span class="source-line-no">2519</span><span id="line-2519"> res = region.checkAndMutate(CheckAndMutate.newBuilder(row1)</span>
<span class="source-line-no">2520</span><span id="line-2520"> .ifMatches(fam1, qf1, CompareOperator.EQUAL, Bytes.toBytes(bd1)).build(delete));</span>
<span class="source-line-no">2521</span><span id="line-2521"> assertTrue("Second delete", res.isSuccess());</span>
<span class="source-line-no">2522</span><span id="line-2522"> assertNull(res.getResult());</span>
<span class="source-line-no">2523</span><span id="line-2523"> }</span>
<span class="source-line-no">2524</span><span id="line-2524"></span>
<span class="source-line-no">2525</span><span id="line-2525"> @Test</span>
<span class="source-line-no">2526</span><span id="line-2526"> public void testCheckAndMutateWithNonEqualCompareOp() throws IOException {</span>
<span class="source-line-no">2527</span><span id="line-2527"> byte[] row1 = Bytes.toBytes("row1");</span>
<span class="source-line-no">2528</span><span id="line-2528"> byte[] fam1 = Bytes.toBytes("fam1");</span>
<span class="source-line-no">2529</span><span id="line-2529"> byte[] qf1 = Bytes.toBytes("qualifier");</span>
<span class="source-line-no">2530</span><span id="line-2530"> byte[] val1 = Bytes.toBytes("value1");</span>
<span class="source-line-no">2531</span><span id="line-2531"> byte[] val2 = Bytes.toBytes("value2");</span>
<span class="source-line-no">2532</span><span id="line-2532"> byte[] val3 = Bytes.toBytes("value3");</span>
<span class="source-line-no">2533</span><span id="line-2533"> byte[] val4 = Bytes.toBytes("value4");</span>
<span class="source-line-no">2534</span><span id="line-2534"></span>
<span class="source-line-no">2535</span><span id="line-2535"> // Setting up region</span>
<span class="source-line-no">2536</span><span id="line-2536"> this.region = initHRegion(tableName, method, CONF, fam1);</span>
<span class="source-line-no">2537</span><span id="line-2537"> // Putting val3 in key</span>
<span class="source-line-no">2538</span><span id="line-2538"> Put put = new Put(row1);</span>
<span class="source-line-no">2539</span><span id="line-2539"> put.addColumn(fam1, qf1, val3);</span>
<span class="source-line-no">2540</span><span id="line-2540"> region.put(put);</span>
<span class="source-line-no">2541</span><span id="line-2541"></span>
<span class="source-line-no">2542</span><span id="line-2542"> // Test CompareOp.LESS: original = val3, compare with val3, fail</span>
<span class="source-line-no">2543</span><span id="line-2543"> CheckAndMutateResult res = region.checkAndMutate(</span>
<span class="source-line-no">2544</span><span id="line-2544"> CheckAndMutate.newBuilder(row1).ifMatches(fam1, qf1, CompareOperator.LESS, val3).build(put));</span>
<span class="source-line-no">2545</span><span id="line-2545"> assertFalse(res.isSuccess());</span>
<span class="source-line-no">2546</span><span id="line-2546"> assertNull(res.getResult());</span>
<span class="source-line-no">2547</span><span id="line-2547"></span>
<span class="source-line-no">2548</span><span id="line-2548"> // Test CompareOp.LESS: original = val3, compare with val4, fail</span>
<span class="source-line-no">2549</span><span id="line-2549"> res = region.checkAndMutate(</span>
<span class="source-line-no">2550</span><span id="line-2550"> CheckAndMutate.newBuilder(row1).ifMatches(fam1, qf1, CompareOperator.LESS, val4).build(put));</span>
<span class="source-line-no">2551</span><span id="line-2551"> assertFalse(res.isSuccess());</span>
<span class="source-line-no">2552</span><span id="line-2552"> assertNull(res.getResult());</span>
<span class="source-line-no">2553</span><span id="line-2553"></span>
<span class="source-line-no">2554</span><span id="line-2554"> // Test CompareOp.LESS: original = val3, compare with val2,</span>
<span class="source-line-no">2555</span><span id="line-2555"> // succeed (now value = val2)</span>
<span class="source-line-no">2556</span><span id="line-2556"> put = new Put(row1);</span>
<span class="source-line-no">2557</span><span id="line-2557"> put.addColumn(fam1, qf1, val2);</span>
<span class="source-line-no">2558</span><span id="line-2558"> res = region.checkAndMutate(</span>
<span class="source-line-no">2559</span><span id="line-2559"> CheckAndMutate.newBuilder(row1).ifMatches(fam1, qf1, CompareOperator.LESS, val2).build(put));</span>
<span class="source-line-no">2560</span><span id="line-2560"> assertTrue(res.isSuccess());</span>
<span class="source-line-no">2561</span><span id="line-2561"> assertNull(res.getResult());</span>
<span class="source-line-no">2562</span><span id="line-2562"></span>
<span class="source-line-no">2563</span><span id="line-2563"> // Test CompareOp.LESS_OR_EQUAL: original = val2, compare with val3, fail</span>
<span class="source-line-no">2564</span><span id="line-2564"> res = region.checkAndMutate(CheckAndMutate.newBuilder(row1)</span>
<span class="source-line-no">2565</span><span id="line-2565"> .ifMatches(fam1, qf1, CompareOperator.LESS_OR_EQUAL, val3).build(put));</span>
<span class="source-line-no">2566</span><span id="line-2566"> assertFalse(res.isSuccess());</span>
<span class="source-line-no">2567</span><span id="line-2567"> assertNull(res.getResult());</span>
<span class="source-line-no">2568</span><span id="line-2568"></span>
<span class="source-line-no">2569</span><span id="line-2569"> // Test CompareOp.LESS_OR_EQUAL: original = val2, compare with val2,</span>
<span class="source-line-no">2570</span><span id="line-2570"> // succeed (value still = val2)</span>
<span class="source-line-no">2571</span><span id="line-2571"> res = region.checkAndMutate(CheckAndMutate.newBuilder(row1)</span>
<span class="source-line-no">2572</span><span id="line-2572"> .ifMatches(fam1, qf1, CompareOperator.LESS_OR_EQUAL, val2).build(put));</span>
<span class="source-line-no">2573</span><span id="line-2573"> assertTrue(res.isSuccess());</span>
<span class="source-line-no">2574</span><span id="line-2574"> assertNull(res.getResult());</span>
<span class="source-line-no">2575</span><span id="line-2575"></span>
<span class="source-line-no">2576</span><span id="line-2576"> // Test CompareOp.LESS_OR_EQUAL: original = val2, compare with val1,</span>
<span class="source-line-no">2577</span><span id="line-2577"> // succeed (now value = val3)</span>
<span class="source-line-no">2578</span><span id="line-2578"> put = new Put(row1);</span>
<span class="source-line-no">2579</span><span id="line-2579"> put.addColumn(fam1, qf1, val3);</span>
<span class="source-line-no">2580</span><span id="line-2580"> res = region.checkAndMutate(CheckAndMutate.newBuilder(row1)</span>
<span class="source-line-no">2581</span><span id="line-2581"> .ifMatches(fam1, qf1, CompareOperator.LESS_OR_EQUAL, val1).build(put));</span>
<span class="source-line-no">2582</span><span id="line-2582"> assertTrue(res.isSuccess());</span>
<span class="source-line-no">2583</span><span id="line-2583"> assertNull(res.getResult());</span>
<span class="source-line-no">2584</span><span id="line-2584"></span>
<span class="source-line-no">2585</span><span id="line-2585"> // Test CompareOp.GREATER: original = val3, compare with val3, fail</span>
<span class="source-line-no">2586</span><span id="line-2586"> res = region.checkAndMutate(CheckAndMutate.newBuilder(row1)</span>
<span class="source-line-no">2587</span><span id="line-2587"> .ifMatches(fam1, qf1, CompareOperator.GREATER, val3).build(put));</span>
<span class="source-line-no">2588</span><span id="line-2588"> assertFalse(res.isSuccess());</span>
<span class="source-line-no">2589</span><span id="line-2589"> assertNull(res.getResult());</span>
<span class="source-line-no">2590</span><span id="line-2590"></span>
<span class="source-line-no">2591</span><span id="line-2591"> // Test CompareOp.GREATER: original = val3, compare with val2, fail</span>
<span class="source-line-no">2592</span><span id="line-2592"> res = region.checkAndMutate(CheckAndMutate.newBuilder(row1)</span>
<span class="source-line-no">2593</span><span id="line-2593"> .ifMatches(fam1, qf1, CompareOperator.GREATER, val2).build(put));</span>
<span class="source-line-no">2594</span><span id="line-2594"> assertFalse(res.isSuccess());</span>
<span class="source-line-no">2595</span><span id="line-2595"> assertNull(res.getResult());</span>
<span class="source-line-no">2596</span><span id="line-2596"></span>
<span class="source-line-no">2597</span><span id="line-2597"> // Test CompareOp.GREATER: original = val3, compare with val4,</span>
<span class="source-line-no">2598</span><span id="line-2598"> // succeed (now value = val2)</span>
<span class="source-line-no">2599</span><span id="line-2599"> put = new Put(row1);</span>
<span class="source-line-no">2600</span><span id="line-2600"> put.addColumn(fam1, qf1, val2);</span>
<span class="source-line-no">2601</span><span id="line-2601"> res = region.checkAndMutate(CheckAndMutate.newBuilder(row1)</span>
<span class="source-line-no">2602</span><span id="line-2602"> .ifMatches(fam1, qf1, CompareOperator.GREATER, val4).build(put));</span>
<span class="source-line-no">2603</span><span id="line-2603"> assertTrue(res.isSuccess());</span>
<span class="source-line-no">2604</span><span id="line-2604"> assertNull(res.getResult());</span>
<span class="source-line-no">2605</span><span id="line-2605"></span>
<span class="source-line-no">2606</span><span id="line-2606"> // Test CompareOp.GREATER_OR_EQUAL: original = val2, compare with val1, fail</span>
<span class="source-line-no">2607</span><span id="line-2607"> res = region.checkAndMutate(CheckAndMutate.newBuilder(row1)</span>
<span class="source-line-no">2608</span><span id="line-2608"> .ifMatches(fam1, qf1, CompareOperator.GREATER_OR_EQUAL, val1).build(put));</span>
<span class="source-line-no">2609</span><span id="line-2609"> assertFalse(res.isSuccess());</span>
<span class="source-line-no">2610</span><span id="line-2610"> assertNull(res.getResult());</span>
<span class="source-line-no">2611</span><span id="line-2611"></span>
<span class="source-line-no">2612</span><span id="line-2612"> // Test CompareOp.GREATER_OR_EQUAL: original = val2, compare with val2,</span>
<span class="source-line-no">2613</span><span id="line-2613"> // succeed (value still = val2)</span>
<span class="source-line-no">2614</span><span id="line-2614"> res = region.checkAndMutate(CheckAndMutate.newBuilder(row1)</span>
<span class="source-line-no">2615</span><span id="line-2615"> .ifMatches(fam1, qf1, CompareOperator.GREATER_OR_EQUAL, val2).build(put));</span>
<span class="source-line-no">2616</span><span id="line-2616"> assertTrue(res.isSuccess());</span>
<span class="source-line-no">2617</span><span id="line-2617"> assertNull(res.getResult());</span>
<span class="source-line-no">2618</span><span id="line-2618"></span>
<span class="source-line-no">2619</span><span id="line-2619"> // Test CompareOp.GREATER_OR_EQUAL: original = val2, compare with val3, succeed</span>
<span class="source-line-no">2620</span><span id="line-2620"> res = region.checkAndMutate(CheckAndMutate.newBuilder(row1)</span>
<span class="source-line-no">2621</span><span id="line-2621"> .ifMatches(fam1, qf1, CompareOperator.GREATER_OR_EQUAL, val3).build(put));</span>
<span class="source-line-no">2622</span><span id="line-2622"> assertTrue(res.isSuccess());</span>
<span class="source-line-no">2623</span><span id="line-2623"> assertNull(res.getResult());</span>
<span class="source-line-no">2624</span><span id="line-2624"> }</span>
<span class="source-line-no">2625</span><span id="line-2625"></span>
<span class="source-line-no">2626</span><span id="line-2626"> @Test</span>
<span class="source-line-no">2627</span><span id="line-2627"> public void testCheckAndPutThatPutWasWritten() throws IOException {</span>
<span class="source-line-no">2628</span><span id="line-2628"> byte[] row1 = Bytes.toBytes("row1");</span>
<span class="source-line-no">2629</span><span id="line-2629"> byte[] fam1 = Bytes.toBytes("fam1");</span>
<span class="source-line-no">2630</span><span id="line-2630"> byte[] fam2 = Bytes.toBytes("fam2");</span>
<span class="source-line-no">2631</span><span id="line-2631"> byte[] qf1 = Bytes.toBytes("qualifier");</span>
<span class="source-line-no">2632</span><span id="line-2632"> byte[] val1 = Bytes.toBytes("value1");</span>
<span class="source-line-no">2633</span><span id="line-2633"> byte[] val2 = Bytes.toBytes("value2");</span>
<span class="source-line-no">2634</span><span id="line-2634"></span>
<span class="source-line-no">2635</span><span id="line-2635"> byte[][] families = { fam1, fam2 };</span>
<span class="source-line-no">2636</span><span id="line-2636"></span>
<span class="source-line-no">2637</span><span id="line-2637"> // Setting up region</span>
<span class="source-line-no">2638</span><span id="line-2638"> this.region = initHRegion(tableName, method, CONF, families);</span>
<span class="source-line-no">2639</span><span id="line-2639"> // Putting data in the key to check</span>
<span class="source-line-no">2640</span><span id="line-2640"> Put put = new Put(row1);</span>
<span class="source-line-no">2641</span><span id="line-2641"> put.addColumn(fam1, qf1, val1);</span>
<span class="source-line-no">2642</span><span id="line-2642"> region.put(put);</span>
<span class="source-line-no">2643</span><span id="line-2643"></span>
<span class="source-line-no">2644</span><span id="line-2644"> // Creating put to add</span>
<span class="source-line-no">2645</span><span id="line-2645"> long ts = EnvironmentEdgeManager.currentTime();</span>
<span class="source-line-no">2646</span><span id="line-2646"> KeyValue kv = new KeyValue(row1, fam2, qf1, ts, KeyValue.Type.Put, val2);</span>
<span class="source-line-no">2647</span><span id="line-2647"> put = new Put(row1);</span>
<span class="source-line-no">2648</span><span id="line-2648"> put.add(kv);</span>
<span class="source-line-no">2649</span><span id="line-2649"></span>
<span class="source-line-no">2650</span><span id="line-2650"> // checkAndPut with wrong value</span>
<span class="source-line-no">2651</span><span id="line-2651"> CheckAndMutateResult res = region.checkAndMutate(</span>
<span class="source-line-no">2652</span><span id="line-2652"> CheckAndMutate.newBuilder(row1).ifMatches(fam1, qf1, CompareOperator.EQUAL, val1).build(put));</span>
<span class="source-line-no">2653</span><span id="line-2653"> assertTrue(res.isSuccess());</span>
<span class="source-line-no">2654</span><span id="line-2654"> assertNull(res.getResult());</span>
<span class="source-line-no">2655</span><span id="line-2655"></span>
<span class="source-line-no">2656</span><span id="line-2656"> Get get = new Get(row1);</span>
<span class="source-line-no">2657</span><span id="line-2657"> get.addColumn(fam2, qf1);</span>
<span class="source-line-no">2658</span><span id="line-2658"> Cell[] actual = region.get(get).rawCells();</span>
<span class="source-line-no">2659</span><span id="line-2659"></span>
<span class="source-line-no">2660</span><span id="line-2660"> Cell[] expected = { kv };</span>
<span class="source-line-no">2661</span><span id="line-2661"></span>
<span class="source-line-no">2662</span><span id="line-2662"> assertEquals(expected.length, actual.length);</span>
<span class="source-line-no">2663</span><span id="line-2663"> for (int i = 0; i &lt; actual.length; i++) {</span>
<span class="source-line-no">2664</span><span id="line-2664"> assertEquals(expected[i], actual[i]);</span>
<span class="source-line-no">2665</span><span id="line-2665"> }</span>
<span class="source-line-no">2666</span><span id="line-2666"> }</span>
<span class="source-line-no">2667</span><span id="line-2667"></span>
<span class="source-line-no">2668</span><span id="line-2668"> @Test</span>
<span class="source-line-no">2669</span><span id="line-2669"> public void testCheckAndDeleteThatDeleteWasWritten() throws IOException {</span>
<span class="source-line-no">2670</span><span id="line-2670"> byte[] row1 = Bytes.toBytes("row1");</span>
<span class="source-line-no">2671</span><span id="line-2671"> byte[] fam1 = Bytes.toBytes("fam1");</span>
<span class="source-line-no">2672</span><span id="line-2672"> byte[] fam2 = Bytes.toBytes("fam2");</span>
<span class="source-line-no">2673</span><span id="line-2673"> byte[] qf1 = Bytes.toBytes("qualifier1");</span>
<span class="source-line-no">2674</span><span id="line-2674"> byte[] qf2 = Bytes.toBytes("qualifier2");</span>
<span class="source-line-no">2675</span><span id="line-2675"> byte[] qf3 = Bytes.toBytes("qualifier3");</span>
<span class="source-line-no">2676</span><span id="line-2676"> byte[] val1 = Bytes.toBytes("value1");</span>
<span class="source-line-no">2677</span><span id="line-2677"> byte[] val2 = Bytes.toBytes("value2");</span>
<span class="source-line-no">2678</span><span id="line-2678"> byte[] val3 = Bytes.toBytes("value3");</span>
<span class="source-line-no">2679</span><span id="line-2679"> byte[] emptyVal = new byte[] {};</span>
<span class="source-line-no">2680</span><span id="line-2680"></span>
<span class="source-line-no">2681</span><span id="line-2681"> byte[][] families = { fam1, fam2 };</span>
<span class="source-line-no">2682</span><span id="line-2682"></span>
<span class="source-line-no">2683</span><span id="line-2683"> // Setting up region</span>
<span class="source-line-no">2684</span><span id="line-2684"> this.region = initHRegion(tableName, method, CONF, families);</span>
<span class="source-line-no">2685</span><span id="line-2685"> // Put content</span>
<span class="source-line-no">2686</span><span id="line-2686"> Put put = new Put(row1);</span>
<span class="source-line-no">2687</span><span id="line-2687"> put.addColumn(fam1, qf1, val1);</span>
<span class="source-line-no">2688</span><span id="line-2688"> region.put(put);</span>
<span class="source-line-no">2689</span><span id="line-2689"> Threads.sleep(2);</span>
<span class="source-line-no">2690</span><span id="line-2690"></span>
<span class="source-line-no">2691</span><span id="line-2691"> put = new Put(row1);</span>
<span class="source-line-no">2692</span><span id="line-2692"> put.addColumn(fam1, qf1, val2);</span>
<span class="source-line-no">2693</span><span id="line-2693"> put.addColumn(fam2, qf1, val3);</span>
<span class="source-line-no">2694</span><span id="line-2694"> put.addColumn(fam2, qf2, val2);</span>
<span class="source-line-no">2695</span><span id="line-2695"> put.addColumn(fam2, qf3, val1);</span>
<span class="source-line-no">2696</span><span id="line-2696"> put.addColumn(fam1, qf3, val1);</span>
<span class="source-line-no">2697</span><span id="line-2697"> region.put(put);</span>
<span class="source-line-no">2698</span><span id="line-2698"></span>
<span class="source-line-no">2699</span><span id="line-2699"> LOG.info("get={}", region.get(new Get(row1).addColumn(fam1, qf1)).toString());</span>
<span class="source-line-no">2700</span><span id="line-2700"></span>
<span class="source-line-no">2701</span><span id="line-2701"> // Multi-column delete</span>
<span class="source-line-no">2702</span><span id="line-2702"> Delete delete = new Delete(row1);</span>
<span class="source-line-no">2703</span><span id="line-2703"> delete.addColumn(fam1, qf1);</span>
<span class="source-line-no">2704</span><span id="line-2704"> delete.addColumn(fam2, qf1);</span>
<span class="source-line-no">2705</span><span id="line-2705"> delete.addColumn(fam1, qf3);</span>
<span class="source-line-no">2706</span><span id="line-2706"> CheckAndMutateResult res = region.checkAndMutate(CheckAndMutate.newBuilder(row1)</span>
<span class="source-line-no">2707</span><span id="line-2707"> .ifMatches(fam1, qf1, CompareOperator.EQUAL, val2).build(delete));</span>
<span class="source-line-no">2708</span><span id="line-2708"> assertTrue(res.isSuccess());</span>
<span class="source-line-no">2709</span><span id="line-2709"> assertNull(res.getResult());</span>
<span class="source-line-no">2710</span><span id="line-2710"></span>
<span class="source-line-no">2711</span><span id="line-2711"> Get get = new Get(row1);</span>
<span class="source-line-no">2712</span><span id="line-2712"> get.addColumn(fam1, qf1);</span>
<span class="source-line-no">2713</span><span id="line-2713"> get.addColumn(fam1, qf3);</span>
<span class="source-line-no">2714</span><span id="line-2714"> get.addColumn(fam2, qf2);</span>
<span class="source-line-no">2715</span><span id="line-2715"> Result r = region.get(get);</span>
<span class="source-line-no">2716</span><span id="line-2716"> assertEquals(2, r.size());</span>
<span class="source-line-no">2717</span><span id="line-2717"> assertArrayEquals(val1, r.getValue(fam1, qf1));</span>
<span class="source-line-no">2718</span><span id="line-2718"> assertArrayEquals(val2, r.getValue(fam2, qf2));</span>
<span class="source-line-no">2719</span><span id="line-2719"></span>
<span class="source-line-no">2720</span><span id="line-2720"> // Family delete</span>
<span class="source-line-no">2721</span><span id="line-2721"> delete = new Delete(row1);</span>
<span class="source-line-no">2722</span><span id="line-2722"> delete.addFamily(fam2);</span>
<span class="source-line-no">2723</span><span id="line-2723"> res = region.checkAndMutate(CheckAndMutate.newBuilder(row1)</span>
<span class="source-line-no">2724</span><span id="line-2724"> .ifMatches(fam2, qf1, CompareOperator.EQUAL, emptyVal).build(delete));</span>
<span class="source-line-no">2725</span><span id="line-2725"> assertTrue(res.isSuccess());</span>
<span class="source-line-no">2726</span><span id="line-2726"> assertNull(res.getResult());</span>
<span class="source-line-no">2727</span><span id="line-2727"></span>
<span class="source-line-no">2728</span><span id="line-2728"> get = new Get(row1);</span>
<span class="source-line-no">2729</span><span id="line-2729"> r = region.get(get);</span>
<span class="source-line-no">2730</span><span id="line-2730"> assertEquals(1, r.size());</span>
<span class="source-line-no">2731</span><span id="line-2731"> assertArrayEquals(val1, r.getValue(fam1, qf1));</span>
<span class="source-line-no">2732</span><span id="line-2732"></span>
<span class="source-line-no">2733</span><span id="line-2733"> // Row delete</span>
<span class="source-line-no">2734</span><span id="line-2734"> delete = new Delete(row1);</span>
<span class="source-line-no">2735</span><span id="line-2735"> res = region.checkAndMutate(CheckAndMutate.newBuilder(row1)</span>
<span class="source-line-no">2736</span><span id="line-2736"> .ifMatches(fam1, qf1, CompareOperator.EQUAL, val1).build(delete));</span>
<span class="source-line-no">2737</span><span id="line-2737"> assertTrue(res.isSuccess());</span>
<span class="source-line-no">2738</span><span id="line-2738"> assertNull(res.getResult());</span>
<span class="source-line-no">2739</span><span id="line-2739"></span>
<span class="source-line-no">2740</span><span id="line-2740"> get = new Get(row1);</span>
<span class="source-line-no">2741</span><span id="line-2741"> r = region.get(get);</span>
<span class="source-line-no">2742</span><span id="line-2742"> assertEquals(0, r.size());</span>
<span class="source-line-no">2743</span><span id="line-2743"> }</span>
<span class="source-line-no">2744</span><span id="line-2744"></span>
<span class="source-line-no">2745</span><span id="line-2745"> @Test</span>
<span class="source-line-no">2746</span><span id="line-2746"> public void testCheckAndMutateWithFilters() throws Throwable {</span>
<span class="source-line-no">2747</span><span id="line-2747"> final byte[] FAMILY = Bytes.toBytes("fam");</span>
<span class="source-line-no">2748</span><span id="line-2748"></span>
<span class="source-line-no">2749</span><span id="line-2749"> // Setting up region</span>
<span class="source-line-no">2750</span><span id="line-2750"> this.region = initHRegion(tableName, method, CONF, FAMILY);</span>
<span class="source-line-no">2751</span><span id="line-2751"></span>
<span class="source-line-no">2752</span><span id="line-2752"> // Put one row</span>
<span class="source-line-no">2753</span><span id="line-2753"> Put put = new Put(row);</span>
<span class="source-line-no">2754</span><span id="line-2754"> put.addColumn(FAMILY, Bytes.toBytes("A"), Bytes.toBytes("a"));</span>
<span class="source-line-no">2755</span><span id="line-2755"> put.addColumn(FAMILY, Bytes.toBytes("B"), Bytes.toBytes("b"));</span>
<span class="source-line-no">2756</span><span id="line-2756"> put.addColumn(FAMILY, Bytes.toBytes("C"), Bytes.toBytes("c"));</span>
<span class="source-line-no">2757</span><span id="line-2757"> region.put(put);</span>
<span class="source-line-no">2758</span><span id="line-2758"></span>
<span class="source-line-no">2759</span><span id="line-2759"> // Put with success</span>
<span class="source-line-no">2760</span><span id="line-2760"> CheckAndMutateResult res = region.checkAndMutate(CheckAndMutate.newBuilder(row)</span>
<span class="source-line-no">2761</span><span id="line-2761"> .ifMatches(new FilterList(</span>
<span class="source-line-no">2762</span><span id="line-2762"> new SingleColumnValueFilter(FAMILY, Bytes.toBytes("A"), CompareOperator.EQUAL,</span>
<span class="source-line-no">2763</span><span id="line-2763"> Bytes.toBytes("a")),</span>
<span class="source-line-no">2764</span><span id="line-2764"> new SingleColumnValueFilter(FAMILY, Bytes.toBytes("B"), CompareOperator.EQUAL,</span>
<span class="source-line-no">2765</span><span id="line-2765"> Bytes.toBytes("b"))))</span>
<span class="source-line-no">2766</span><span id="line-2766"> .build(new Put(row).addColumn(FAMILY, Bytes.toBytes("D"), Bytes.toBytes("d"))));</span>
<span class="source-line-no">2767</span><span id="line-2767"> assertTrue(res.isSuccess());</span>
<span class="source-line-no">2768</span><span id="line-2768"> assertNull(res.getResult());</span>
<span class="source-line-no">2769</span><span id="line-2769"></span>
<span class="source-line-no">2770</span><span id="line-2770"> Result result = region.get(new Get(row).addColumn(FAMILY, Bytes.toBytes("D")));</span>
<span class="source-line-no">2771</span><span id="line-2771"> assertEquals("d", Bytes.toString(result.getValue(FAMILY, Bytes.toBytes("D"))));</span>
<span class="source-line-no">2772</span><span id="line-2772"></span>
<span class="source-line-no">2773</span><span id="line-2773"> // Put with failure</span>
<span class="source-line-no">2774</span><span id="line-2774"> res = region.checkAndMutate(CheckAndMutate.newBuilder(row)</span>
<span class="source-line-no">2775</span><span id="line-2775"> .ifMatches(new FilterList(</span>
<span class="source-line-no">2776</span><span id="line-2776"> new SingleColumnValueFilter(FAMILY, Bytes.toBytes("A"), CompareOperator.EQUAL,</span>
<span class="source-line-no">2777</span><span id="line-2777"> Bytes.toBytes("a")),</span>
<span class="source-line-no">2778</span><span id="line-2778"> new SingleColumnValueFilter(FAMILY, Bytes.toBytes("B"), CompareOperator.EQUAL,</span>
<span class="source-line-no">2779</span><span id="line-2779"> Bytes.toBytes("c"))))</span>
<span class="source-line-no">2780</span><span id="line-2780"> .build(new Put(row).addColumn(FAMILY, Bytes.toBytes("E"), Bytes.toBytes("e"))));</span>
<span class="source-line-no">2781</span><span id="line-2781"> assertFalse(res.isSuccess());</span>
<span class="source-line-no">2782</span><span id="line-2782"> assertNull(res.getResult());</span>
<span class="source-line-no">2783</span><span id="line-2783"></span>
<span class="source-line-no">2784</span><span id="line-2784"> assertTrue(region.get(new Get(row).addColumn(FAMILY, Bytes.toBytes("E"))).isEmpty());</span>
<span class="source-line-no">2785</span><span id="line-2785"></span>
<span class="source-line-no">2786</span><span id="line-2786"> // Delete with success</span>
<span class="source-line-no">2787</span><span id="line-2787"> res = region.checkAndMutate(CheckAndMutate.newBuilder(row)</span>
<span class="source-line-no">2788</span><span id="line-2788"> .ifMatches(new FilterList(</span>
<span class="source-line-no">2789</span><span id="line-2789"> new SingleColumnValueFilter(FAMILY, Bytes.toBytes("A"), CompareOperator.EQUAL,</span>
<span class="source-line-no">2790</span><span id="line-2790"> Bytes.toBytes("a")),</span>
<span class="source-line-no">2791</span><span id="line-2791"> new SingleColumnValueFilter(FAMILY, Bytes.toBytes("B"), CompareOperator.EQUAL,</span>
<span class="source-line-no">2792</span><span id="line-2792"> Bytes.toBytes("b"))))</span>
<span class="source-line-no">2793</span><span id="line-2793"> .build(new Delete(row).addColumns(FAMILY, Bytes.toBytes("D"))));</span>
<span class="source-line-no">2794</span><span id="line-2794"> assertTrue(res.isSuccess());</span>
<span class="source-line-no">2795</span><span id="line-2795"> assertNull(res.getResult());</span>
<span class="source-line-no">2796</span><span id="line-2796"></span>
<span class="source-line-no">2797</span><span id="line-2797"> assertTrue(region.get(new Get(row).addColumn(FAMILY, Bytes.toBytes("D"))).isEmpty());</span>
<span class="source-line-no">2798</span><span id="line-2798"></span>
<span class="source-line-no">2799</span><span id="line-2799"> // Mutate with success</span>
<span class="source-line-no">2800</span><span id="line-2800"> res = region.checkAndMutate(CheckAndMutate.newBuilder(row)</span>
<span class="source-line-no">2801</span><span id="line-2801"> .ifMatches(new FilterList(</span>
<span class="source-line-no">2802</span><span id="line-2802"> new SingleColumnValueFilter(FAMILY, Bytes.toBytes("A"), CompareOperator.EQUAL,</span>
<span class="source-line-no">2803</span><span id="line-2803"> Bytes.toBytes("a")),</span>
<span class="source-line-no">2804</span><span id="line-2804"> new SingleColumnValueFilter(FAMILY, Bytes.toBytes("B"), CompareOperator.EQUAL,</span>
<span class="source-line-no">2805</span><span id="line-2805"> Bytes.toBytes("b"))))</span>
<span class="source-line-no">2806</span><span id="line-2806"> .build(new RowMutations(row)</span>
<span class="source-line-no">2807</span><span id="line-2807"> .add((Mutation) new Put(row).addColumn(FAMILY, Bytes.toBytes("E"), Bytes.toBytes("e")))</span>
<span class="source-line-no">2808</span><span id="line-2808"> .add((Mutation) new Delete(row).addColumns(FAMILY, Bytes.toBytes("A")))));</span>
<span class="source-line-no">2809</span><span id="line-2809"> assertTrue(res.isSuccess());</span>
<span class="source-line-no">2810</span><span id="line-2810"> assertNull(res.getResult());</span>
<span class="source-line-no">2811</span><span id="line-2811"></span>
<span class="source-line-no">2812</span><span id="line-2812"> result = region.get(new Get(row).addColumn(FAMILY, Bytes.toBytes("E")));</span>
<span class="source-line-no">2813</span><span id="line-2813"> assertEquals("e", Bytes.toString(result.getValue(FAMILY, Bytes.toBytes("E"))));</span>
<span class="source-line-no">2814</span><span id="line-2814"></span>
<span class="source-line-no">2815</span><span id="line-2815"> assertTrue(region.get(new Get(row).addColumn(FAMILY, Bytes.toBytes("A"))).isEmpty());</span>
<span class="source-line-no">2816</span><span id="line-2816"> }</span>
<span class="source-line-no">2817</span><span id="line-2817"></span>
<span class="source-line-no">2818</span><span id="line-2818"> @Test</span>
<span class="source-line-no">2819</span><span id="line-2819"> public void testCheckAndMutateWithFiltersAndTimeRange() throws Throwable {</span>
<span class="source-line-no">2820</span><span id="line-2820"> final byte[] FAMILY = Bytes.toBytes("fam");</span>
<span class="source-line-no">2821</span><span id="line-2821"></span>
<span class="source-line-no">2822</span><span id="line-2822"> // Setting up region</span>
<span class="source-line-no">2823</span><span id="line-2823"> this.region = initHRegion(tableName, method, CONF, FAMILY);</span>
<span class="source-line-no">2824</span><span id="line-2824"></span>
<span class="source-line-no">2825</span><span id="line-2825"> // Put with specifying the timestamp</span>
<span class="source-line-no">2826</span><span id="line-2826"> region.put(new Put(row).addColumn(FAMILY, Bytes.toBytes("A"), 100, Bytes.toBytes("a")));</span>
<span class="source-line-no">2827</span><span id="line-2827"></span>
<span class="source-line-no">2828</span><span id="line-2828"> // Put with success</span>
<span class="source-line-no">2829</span><span id="line-2829"> CheckAndMutateResult res = region.checkAndMutate(CheckAndMutate.newBuilder(row)</span>
<span class="source-line-no">2830</span><span id="line-2830"> .ifMatches(new SingleColumnValueFilter(FAMILY, Bytes.toBytes("A"), CompareOperator.EQUAL,</span>
<span class="source-line-no">2831</span><span id="line-2831"> Bytes.toBytes("a")))</span>
<span class="source-line-no">2832</span><span id="line-2832"> .timeRange(TimeRange.between(0, 101))</span>
<span class="source-line-no">2833</span><span id="line-2833"> .build(new Put(row).addColumn(FAMILY, Bytes.toBytes("B"), Bytes.toBytes("b"))));</span>
<span class="source-line-no">2834</span><span id="line-2834"> assertTrue(res.isSuccess());</span>
<span class="source-line-no">2835</span><span id="line-2835"> assertNull(res.getResult());</span>
<span class="source-line-no">2836</span><span id="line-2836"></span>
<span class="source-line-no">2837</span><span id="line-2837"> Result result = region.get(new Get(row).addColumn(FAMILY, Bytes.toBytes("B")));</span>
<span class="source-line-no">2838</span><span id="line-2838"> assertEquals("b", Bytes.toString(result.getValue(FAMILY, Bytes.toBytes("B"))));</span>
<span class="source-line-no">2839</span><span id="line-2839"></span>
<span class="source-line-no">2840</span><span id="line-2840"> // Put with failure</span>
<span class="source-line-no">2841</span><span id="line-2841"> res = region.checkAndMutate(CheckAndMutate.newBuilder(row)</span>
<span class="source-line-no">2842</span><span id="line-2842"> .ifMatches(new SingleColumnValueFilter(FAMILY, Bytes.toBytes("A"), CompareOperator.EQUAL,</span>
<span class="source-line-no">2843</span><span id="line-2843"> Bytes.toBytes("a")))</span>
<span class="source-line-no">2844</span><span id="line-2844"> .timeRange(TimeRange.between(0, 100))</span>
<span class="source-line-no">2845</span><span id="line-2845"> .build(new Put(row).addColumn(FAMILY, Bytes.toBytes("C"), Bytes.toBytes("c"))));</span>
<span class="source-line-no">2846</span><span id="line-2846"> assertFalse(res.isSuccess());</span>
<span class="source-line-no">2847</span><span id="line-2847"> assertNull(res.getResult());</span>
<span class="source-line-no">2848</span><span id="line-2848"></span>
<span class="source-line-no">2849</span><span id="line-2849"> assertTrue(region.get(new Get(row).addColumn(FAMILY, Bytes.toBytes("C"))).isEmpty());</span>
<span class="source-line-no">2850</span><span id="line-2850"></span>
<span class="source-line-no">2851</span><span id="line-2851"> // RowMutations with success</span>
<span class="source-line-no">2852</span><span id="line-2852"> res = region.checkAndMutate(CheckAndMutate.newBuilder(row)</span>
<span class="source-line-no">2853</span><span id="line-2853"> .ifMatches(new SingleColumnValueFilter(FAMILY, Bytes.toBytes("A"), CompareOperator.EQUAL,</span>
<span class="source-line-no">2854</span><span id="line-2854"> Bytes.toBytes("a")))</span>
<span class="source-line-no">2855</span><span id="line-2855"> .timeRange(TimeRange.between(0, 101))</span>
<span class="source-line-no">2856</span><span id="line-2856"> .build(new RowMutations(row)</span>
<span class="source-line-no">2857</span><span id="line-2857"> .add((Mutation) new Put(row).addColumn(FAMILY, Bytes.toBytes("D"), Bytes.toBytes("d")))</span>
<span class="source-line-no">2858</span><span id="line-2858"> .add((Mutation) new Delete(row).addColumns(FAMILY, Bytes.toBytes("A")))));</span>
<span class="source-line-no">2859</span><span id="line-2859"> assertTrue(res.isSuccess());</span>
<span class="source-line-no">2860</span><span id="line-2860"> assertNull(res.getResult());</span>
<span class="source-line-no">2861</span><span id="line-2861"></span>
<span class="source-line-no">2862</span><span id="line-2862"> result = region.get(new Get(row).addColumn(FAMILY, Bytes.toBytes("D")));</span>
<span class="source-line-no">2863</span><span id="line-2863"> assertEquals("d", Bytes.toString(result.getValue(FAMILY, Bytes.toBytes("D"))));</span>
<span class="source-line-no">2864</span><span id="line-2864"></span>
<span class="source-line-no">2865</span><span id="line-2865"> assertTrue(region.get(new Get(row).addColumn(FAMILY, Bytes.toBytes("A"))).isEmpty());</span>
<span class="source-line-no">2866</span><span id="line-2866"> }</span>
<span class="source-line-no">2867</span><span id="line-2867"></span>
<span class="source-line-no">2868</span><span id="line-2868"> @Test</span>
<span class="source-line-no">2869</span><span id="line-2869"> public void testCheckAndIncrement() throws Throwable {</span>
<span class="source-line-no">2870</span><span id="line-2870"> final byte[] FAMILY = Bytes.toBytes("fam");</span>
<span class="source-line-no">2871</span><span id="line-2871"></span>
<span class="source-line-no">2872</span><span id="line-2872"> // Setting up region</span>
<span class="source-line-no">2873</span><span id="line-2873"> this.region = initHRegion(tableName, method, CONF, FAMILY);</span>
<span class="source-line-no">2874</span><span id="line-2874"></span>
<span class="source-line-no">2875</span><span id="line-2875"> region.put(new Put(row).addColumn(FAMILY, Bytes.toBytes("A"), Bytes.toBytes("a")));</span>
<span class="source-line-no">2876</span><span id="line-2876"></span>
<span class="source-line-no">2877</span><span id="line-2877"> // CheckAndIncrement with correct value</span>
<span class="source-line-no">2878</span><span id="line-2878"> CheckAndMutateResult res = region.checkAndMutate(</span>
<span class="source-line-no">2879</span><span id="line-2879"> CheckAndMutate.newBuilder(row).ifEquals(FAMILY, Bytes.toBytes("A"), Bytes.toBytes("a"))</span>
<span class="source-line-no">2880</span><span id="line-2880"> .build(new Increment(row).addColumn(FAMILY, Bytes.toBytes("B"), 1)));</span>
<span class="source-line-no">2881</span><span id="line-2881"> assertTrue(res.isSuccess());</span>
<span class="source-line-no">2882</span><span id="line-2882"> assertEquals(1, Bytes.toLong(res.getResult().getValue(FAMILY, Bytes.toBytes("B"))));</span>
<span class="source-line-no">2883</span><span id="line-2883"></span>
<span class="source-line-no">2884</span><span id="line-2884"> Result result = region.get(new Get(row).addColumn(FAMILY, Bytes.toBytes("B")));</span>
<span class="source-line-no">2885</span><span id="line-2885"> assertEquals(1, Bytes.toLong(result.getValue(FAMILY, Bytes.toBytes("B"))));</span>
<span class="source-line-no">2886</span><span id="line-2886"></span>
<span class="source-line-no">2887</span><span id="line-2887"> // CheckAndIncrement with wrong value</span>
<span class="source-line-no">2888</span><span id="line-2888"> res = region.checkAndMutate(</span>
<span class="source-line-no">2889</span><span id="line-2889"> CheckAndMutate.newBuilder(row).ifEquals(FAMILY, Bytes.toBytes("A"), Bytes.toBytes("b"))</span>
<span class="source-line-no">2890</span><span id="line-2890"> .build(new Increment(row).addColumn(FAMILY, Bytes.toBytes("B"), 1)));</span>
<span class="source-line-no">2891</span><span id="line-2891"> assertFalse(res.isSuccess());</span>
<span class="source-line-no">2892</span><span id="line-2892"> assertNull(res.getResult());</span>
<span class="source-line-no">2893</span><span id="line-2893"></span>
<span class="source-line-no">2894</span><span id="line-2894"> result = region.get(new Get(row).addColumn(FAMILY, Bytes.toBytes("B")));</span>
<span class="source-line-no">2895</span><span id="line-2895"> assertEquals(1, Bytes.toLong(result.getValue(FAMILY, Bytes.toBytes("B"))));</span>
<span class="source-line-no">2896</span><span id="line-2896"></span>
<span class="source-line-no">2897</span><span id="line-2897"> region.put(new Put(row).addColumn(FAMILY, Bytes.toBytes("C"), Bytes.toBytes("c")));</span>
<span class="source-line-no">2898</span><span id="line-2898"></span>
<span class="source-line-no">2899</span><span id="line-2899"> // CheckAndIncrement with a filter and correct value</span>
<span class="source-line-no">2900</span><span id="line-2900"> res = region.checkAndMutate(CheckAndMutate.newBuilder(row)</span>
<span class="source-line-no">2901</span><span id="line-2901"> .ifMatches(new FilterList(</span>
<span class="source-line-no">2902</span><span id="line-2902"> new SingleColumnValueFilter(FAMILY, Bytes.toBytes("A"), CompareOperator.EQUAL,</span>
<span class="source-line-no">2903</span><span id="line-2903"> Bytes.toBytes("a")),</span>
<span class="source-line-no">2904</span><span id="line-2904"> new SingleColumnValueFilter(FAMILY, Bytes.toBytes("C"), CompareOperator.EQUAL,</span>
<span class="source-line-no">2905</span><span id="line-2905"> Bytes.toBytes("c"))))</span>
<span class="source-line-no">2906</span><span id="line-2906"> .build(new Increment(row).addColumn(FAMILY, Bytes.toBytes("B"), 2)));</span>
<span class="source-line-no">2907</span><span id="line-2907"> assertTrue(res.isSuccess());</span>
<span class="source-line-no">2908</span><span id="line-2908"> assertEquals(3, Bytes.toLong(res.getResult().getValue(FAMILY, Bytes.toBytes("B"))));</span>
<span class="source-line-no">2909</span><span id="line-2909"></span>
<span class="source-line-no">2910</span><span id="line-2910"> result = region.get(new Get(row).addColumn(FAMILY, Bytes.toBytes("B")));</span>
<span class="source-line-no">2911</span><span id="line-2911"> assertEquals(3, Bytes.toLong(result.getValue(FAMILY, Bytes.toBytes("B"))));</span>
<span class="source-line-no">2912</span><span id="line-2912"></span>
<span class="source-line-no">2913</span><span id="line-2913"> // CheckAndIncrement with a filter and correct value</span>
<span class="source-line-no">2914</span><span id="line-2914"> res = region.checkAndMutate(CheckAndMutate.newBuilder(row)</span>
<span class="source-line-no">2915</span><span id="line-2915"> .ifMatches(new FilterList(</span>
<span class="source-line-no">2916</span><span id="line-2916"> new SingleColumnValueFilter(FAMILY, Bytes.toBytes("A"), CompareOperator.EQUAL,</span>
<span class="source-line-no">2917</span><span id="line-2917"> Bytes.toBytes("b")),</span>
<span class="source-line-no">2918</span><span id="line-2918"> new SingleColumnValueFilter(FAMILY, Bytes.toBytes("C"), CompareOperator.EQUAL,</span>
<span class="source-line-no">2919</span><span id="line-2919"> Bytes.toBytes("d"))))</span>
<span class="source-line-no">2920</span><span id="line-2920"> .build(new Increment(row).addColumn(FAMILY, Bytes.toBytes("B"), 2)));</span>
<span class="source-line-no">2921</span><span id="line-2921"> assertFalse(res.isSuccess());</span>
<span class="source-line-no">2922</span><span id="line-2922"> assertNull(res.getResult());</span>
<span class="source-line-no">2923</span><span id="line-2923"></span>
<span class="source-line-no">2924</span><span id="line-2924"> result = region.get(new Get(row).addColumn(FAMILY, Bytes.toBytes("B")));</span>
<span class="source-line-no">2925</span><span id="line-2925"> assertEquals(3, Bytes.toLong(result.getValue(FAMILY, Bytes.toBytes("B"))));</span>
<span class="source-line-no">2926</span><span id="line-2926"> }</span>
<span class="source-line-no">2927</span><span id="line-2927"></span>
<span class="source-line-no">2928</span><span id="line-2928"> @Test</span>
<span class="source-line-no">2929</span><span id="line-2929"> public void testCheckAndAppend() throws Throwable {</span>
<span class="source-line-no">2930</span><span id="line-2930"> final byte[] FAMILY = Bytes.toBytes("fam");</span>
<span class="source-line-no">2931</span><span id="line-2931"></span>
<span class="source-line-no">2932</span><span id="line-2932"> // Setting up region</span>
<span class="source-line-no">2933</span><span id="line-2933"> this.region = initHRegion(tableName, method, CONF, FAMILY);</span>
<span class="source-line-no">2934</span><span id="line-2934"></span>
<span class="source-line-no">2935</span><span id="line-2935"> region.put(new Put(row).addColumn(FAMILY, Bytes.toBytes("A"), Bytes.toBytes("a")));</span>
<span class="source-line-no">2936</span><span id="line-2936"></span>
<span class="source-line-no">2937</span><span id="line-2937"> // CheckAndAppend with correct value</span>
<span class="source-line-no">2938</span><span id="line-2938"> CheckAndMutateResult res = region.checkAndMutate(</span>
<span class="source-line-no">2939</span><span id="line-2939"> CheckAndMutate.newBuilder(row).ifEquals(FAMILY, Bytes.toBytes("A"), Bytes.toBytes("a"))</span>
<span class="source-line-no">2940</span><span id="line-2940"> .build(new Append(row).addColumn(FAMILY, Bytes.toBytes("B"), Bytes.toBytes("b"))));</span>
<span class="source-line-no">2941</span><span id="line-2941"> assertTrue(res.isSuccess());</span>
<span class="source-line-no">2942</span><span id="line-2942"> assertEquals("b", Bytes.toString(res.getResult().getValue(FAMILY, Bytes.toBytes("B"))));</span>
<span class="source-line-no">2943</span><span id="line-2943"></span>
<span class="source-line-no">2944</span><span id="line-2944"> Result result = region.get(new Get(row).addColumn(FAMILY, Bytes.toBytes("B")));</span>
<span class="source-line-no">2945</span><span id="line-2945"> assertEquals("b", Bytes.toString(result.getValue(FAMILY, Bytes.toBytes("B"))));</span>
<span class="source-line-no">2946</span><span id="line-2946"></span>
<span class="source-line-no">2947</span><span id="line-2947"> // CheckAndAppend with wrong value</span>
<span class="source-line-no">2948</span><span id="line-2948"> res = region.checkAndMutate(</span>
<span class="source-line-no">2949</span><span id="line-2949"> CheckAndMutate.newBuilder(row).ifEquals(FAMILY, Bytes.toBytes("A"), Bytes.toBytes("b"))</span>
<span class="source-line-no">2950</span><span id="line-2950"> .build(new Append(row).addColumn(FAMILY, Bytes.toBytes("B"), Bytes.toBytes("b"))));</span>
<span class="source-line-no">2951</span><span id="line-2951"> assertFalse(res.isSuccess());</span>
<span class="source-line-no">2952</span><span id="line-2952"> assertNull(res.getResult());</span>
<span class="source-line-no">2953</span><span id="line-2953"></span>
<span class="source-line-no">2954</span><span id="line-2954"> result = region.get(new Get(row).addColumn(FAMILY, Bytes.toBytes("B")));</span>
<span class="source-line-no">2955</span><span id="line-2955"> assertEquals("b", Bytes.toString(result.getValue(FAMILY, Bytes.toBytes("B"))));</span>
<span class="source-line-no">2956</span><span id="line-2956"></span>
<span class="source-line-no">2957</span><span id="line-2957"> region.put(new Put(row).addColumn(FAMILY, Bytes.toBytes("C"), Bytes.toBytes("c")));</span>
<span class="source-line-no">2958</span><span id="line-2958"></span>
<span class="source-line-no">2959</span><span id="line-2959"> // CheckAndAppend with a filter and correct value</span>
<span class="source-line-no">2960</span><span id="line-2960"> res = region.checkAndMutate(CheckAndMutate.newBuilder(row)</span>
<span class="source-line-no">2961</span><span id="line-2961"> .ifMatches(new FilterList(</span>
<span class="source-line-no">2962</span><span id="line-2962"> new SingleColumnValueFilter(FAMILY, Bytes.toBytes("A"), CompareOperator.EQUAL,</span>
<span class="source-line-no">2963</span><span id="line-2963"> Bytes.toBytes("a")),</span>
<span class="source-line-no">2964</span><span id="line-2964"> new SingleColumnValueFilter(FAMILY, Bytes.toBytes("C"), CompareOperator.EQUAL,</span>
<span class="source-line-no">2965</span><span id="line-2965"> Bytes.toBytes("c"))))</span>
<span class="source-line-no">2966</span><span id="line-2966"> .build(new Append(row).addColumn(FAMILY, Bytes.toBytes("B"), Bytes.toBytes("bb"))));</span>
<span class="source-line-no">2967</span><span id="line-2967"> assertTrue(res.isSuccess());</span>
<span class="source-line-no">2968</span><span id="line-2968"> assertEquals("bbb", Bytes.toString(res.getResult().getValue(FAMILY, Bytes.toBytes("B"))));</span>
<span class="source-line-no">2969</span><span id="line-2969"></span>
<span class="source-line-no">2970</span><span id="line-2970"> result = region.get(new Get(row).addColumn(FAMILY, Bytes.toBytes("B")));</span>
<span class="source-line-no">2971</span><span id="line-2971"> assertEquals("bbb", Bytes.toString(result.getValue(FAMILY, Bytes.toBytes("B"))));</span>
<span class="source-line-no">2972</span><span id="line-2972"></span>
<span class="source-line-no">2973</span><span id="line-2973"> // CheckAndAppend with a filter and wrong value</span>
<span class="source-line-no">2974</span><span id="line-2974"> res = region.checkAndMutate(CheckAndMutate.newBuilder(row)</span>
<span class="source-line-no">2975</span><span id="line-2975"> .ifMatches(new FilterList(</span>
<span class="source-line-no">2976</span><span id="line-2976"> new SingleColumnValueFilter(FAMILY, Bytes.toBytes("A"), CompareOperator.EQUAL,</span>
<span class="source-line-no">2977</span><span id="line-2977"> Bytes.toBytes("b")),</span>
<span class="source-line-no">2978</span><span id="line-2978"> new SingleColumnValueFilter(FAMILY, Bytes.toBytes("C"), CompareOperator.EQUAL,</span>
<span class="source-line-no">2979</span><span id="line-2979"> Bytes.toBytes("d"))))</span>
<span class="source-line-no">2980</span><span id="line-2980"> .build(new Append(row).addColumn(FAMILY, Bytes.toBytes("B"), Bytes.toBytes("bb"))));</span>
<span class="source-line-no">2981</span><span id="line-2981"> assertFalse(res.isSuccess());</span>
<span class="source-line-no">2982</span><span id="line-2982"> assertNull(res.getResult());</span>
<span class="source-line-no">2983</span><span id="line-2983"></span>
<span class="source-line-no">2984</span><span id="line-2984"> result = region.get(new Get(row).addColumn(FAMILY, Bytes.toBytes("B")));</span>
<span class="source-line-no">2985</span><span id="line-2985"> assertEquals("bbb", Bytes.toString(result.getValue(FAMILY, Bytes.toBytes("B"))));</span>
<span class="source-line-no">2986</span><span id="line-2986"> }</span>
<span class="source-line-no">2987</span><span id="line-2987"></span>
<span class="source-line-no">2988</span><span id="line-2988"> @Test</span>
<span class="source-line-no">2989</span><span id="line-2989"> public void testCheckAndIncrementAndAppend() throws Throwable {</span>
<span class="source-line-no">2990</span><span id="line-2990"> // Setting up region</span>
<span class="source-line-no">2991</span><span id="line-2991"> this.region = initHRegion(tableName, method, CONF, fam1);</span>
<span class="source-line-no">2992</span><span id="line-2992"></span>
<span class="source-line-no">2993</span><span id="line-2993"> // CheckAndMutate with Increment and Append</span>
<span class="source-line-no">2994</span><span id="line-2994"> CheckAndMutate checkAndMutate = CheckAndMutate.newBuilder(row).ifNotExists(fam1, qual)</span>
<span class="source-line-no">2995</span><span id="line-2995"> .build(new RowMutations(row).add((Mutation) new Increment(row).addColumn(fam1, qual1, 1L))</span>
<span class="source-line-no">2996</span><span id="line-2996"> .add((Mutation) new Append(row).addColumn(fam1, qual2, Bytes.toBytes("a"))));</span>
<span class="source-line-no">2997</span><span id="line-2997"></span>
<span class="source-line-no">2998</span><span id="line-2998"> CheckAndMutateResult result = region.checkAndMutate(checkAndMutate);</span>
<span class="source-line-no">2999</span><span id="line-2999"> assertTrue(result.isSuccess());</span>
<span class="source-line-no">3000</span><span id="line-3000"> assertEquals(1L, Bytes.toLong(result.getResult().getValue(fam1, qual1)));</span>
<span class="source-line-no">3001</span><span id="line-3001"> assertEquals("a", Bytes.toString(result.getResult().getValue(fam1, qual2)));</span>
<span class="source-line-no">3002</span><span id="line-3002"></span>
<span class="source-line-no">3003</span><span id="line-3003"> Result r = region.get(new Get(row));</span>
<span class="source-line-no">3004</span><span id="line-3004"> assertEquals(1L, Bytes.toLong(r.getValue(fam1, qual1)));</span>
<span class="source-line-no">3005</span><span id="line-3005"> assertEquals("a", Bytes.toString(r.getValue(fam1, qual2)));</span>
<span class="source-line-no">3006</span><span id="line-3006"></span>
<span class="source-line-no">3007</span><span id="line-3007"> // Set return results to false</span>
<span class="source-line-no">3008</span><span id="line-3008"> checkAndMutate = CheckAndMutate.newBuilder(row).ifNotExists(fam1, qual)</span>
<span class="source-line-no">3009</span><span id="line-3009"> .build(new RowMutations(row)</span>
<span class="source-line-no">3010</span><span id="line-3010"> .add((Mutation) new Increment(row).addColumn(fam1, qual1, 1L).setReturnResults(false))</span>
<span class="source-line-no">3011</span><span id="line-3011"> .add((Mutation) new Append(row).addColumn(fam1, qual2, Bytes.toBytes("a"))</span>
<span class="source-line-no">3012</span><span id="line-3012"> .setReturnResults(false)));</span>
<span class="source-line-no">3013</span><span id="line-3013"></span>
<span class="source-line-no">3014</span><span id="line-3014"> result = region.checkAndMutate(checkAndMutate);</span>
<span class="source-line-no">3015</span><span id="line-3015"> assertTrue(result.isSuccess());</span>
<span class="source-line-no">3016</span><span id="line-3016"> assertNull(result.getResult().getValue(fam1, qual1));</span>
<span class="source-line-no">3017</span><span id="line-3017"> assertNull(result.getResult().getValue(fam1, qual2));</span>
<span class="source-line-no">3018</span><span id="line-3018"></span>
<span class="source-line-no">3019</span><span id="line-3019"> r = region.get(new Get(row));</span>
<span class="source-line-no">3020</span><span id="line-3020"> assertEquals(2L, Bytes.toLong(r.getValue(fam1, qual1)));</span>
<span class="source-line-no">3021</span><span id="line-3021"> assertEquals("aa", Bytes.toString(r.getValue(fam1, qual2)));</span>
<span class="source-line-no">3022</span><span id="line-3022"></span>
<span class="source-line-no">3023</span><span id="line-3023"> checkAndMutate = CheckAndMutate.newBuilder(row).ifNotExists(fam1, qual)</span>
<span class="source-line-no">3024</span><span id="line-3024"> .build(new RowMutations(row).add((Mutation) new Increment(row).addColumn(fam1, qual1, 1L))</span>
<span class="source-line-no">3025</span><span id="line-3025"> .add((Mutation) new Append(row).addColumn(fam1, qual2, Bytes.toBytes("a"))</span>
<span class="source-line-no">3026</span><span id="line-3026"> .setReturnResults(false)));</span>
<span class="source-line-no">3027</span><span id="line-3027"></span>
<span class="source-line-no">3028</span><span id="line-3028"> result = region.checkAndMutate(checkAndMutate);</span>
<span class="source-line-no">3029</span><span id="line-3029"> assertTrue(result.isSuccess());</span>
<span class="source-line-no">3030</span><span id="line-3030"> assertEquals(3L, Bytes.toLong(result.getResult().getValue(fam1, qual1)));</span>
<span class="source-line-no">3031</span><span id="line-3031"> assertNull(result.getResult().getValue(fam1, qual2));</span>
<span class="source-line-no">3032</span><span id="line-3032"></span>
<span class="source-line-no">3033</span><span id="line-3033"> r = region.get(new Get(row));</span>
<span class="source-line-no">3034</span><span id="line-3034"> assertEquals(3L, Bytes.toLong(r.getValue(fam1, qual1)));</span>
<span class="source-line-no">3035</span><span id="line-3035"> assertEquals("aaa", Bytes.toString(r.getValue(fam1, qual2)));</span>
<span class="source-line-no">3036</span><span id="line-3036"> }</span>
<span class="source-line-no">3037</span><span id="line-3037"></span>
<span class="source-line-no">3038</span><span id="line-3038"> @Test</span>
<span class="source-line-no">3039</span><span id="line-3039"> public void testCheckAndRowMutations() throws Throwable {</span>
<span class="source-line-no">3040</span><span id="line-3040"> final byte[] row = Bytes.toBytes("row");</span>
<span class="source-line-no">3041</span><span id="line-3041"> final byte[] q1 = Bytes.toBytes("q1");</span>
<span class="source-line-no">3042</span><span id="line-3042"> final byte[] q2 = Bytes.toBytes("q2");</span>
<span class="source-line-no">3043</span><span id="line-3043"> final byte[] q3 = Bytes.toBytes("q3");</span>
<span class="source-line-no">3044</span><span id="line-3044"> final byte[] q4 = Bytes.toBytes("q4");</span>
<span class="source-line-no">3045</span><span id="line-3045"> final String v1 = "v1";</span>
<span class="source-line-no">3046</span><span id="line-3046"></span>
<span class="source-line-no">3047</span><span id="line-3047"> region = initHRegion(tableName, method, CONF, fam1);</span>
<span class="source-line-no">3048</span><span id="line-3048"></span>
<span class="source-line-no">3049</span><span id="line-3049"> // Initial values</span>
<span class="source-line-no">3050</span><span id="line-3050"> region</span>
<span class="source-line-no">3051</span><span id="line-3051"> .batchMutate(new Mutation[] { new Put(row).addColumn(fam1, q2, Bytes.toBytes("toBeDeleted")),</span>
<span class="source-line-no">3052</span><span id="line-3052"> new Put(row).addColumn(fam1, q3, Bytes.toBytes(5L)),</span>
<span class="source-line-no">3053</span><span id="line-3053"> new Put(row).addColumn(fam1, q4, Bytes.toBytes("a")), });</span>
<span class="source-line-no">3054</span><span id="line-3054"></span>
<span class="source-line-no">3055</span><span id="line-3055"> // Do CheckAndRowMutations</span>
<span class="source-line-no">3056</span><span id="line-3056"> CheckAndMutate checkAndMutate = CheckAndMutate.newBuilder(row).ifNotExists(fam1, q1).build(</span>
<span class="source-line-no">3057</span><span id="line-3057"> new RowMutations(row).add(Arrays.asList(new Put(row).addColumn(fam1, q1, Bytes.toBytes(v1)),</span>
<span class="source-line-no">3058</span><span id="line-3058"> new Delete(row).addColumns(fam1, q2), new Increment(row).addColumn(fam1, q3, 1),</span>
<span class="source-line-no">3059</span><span id="line-3059"> new Append(row).addColumn(fam1, q4, Bytes.toBytes("b")))));</span>
<span class="source-line-no">3060</span><span id="line-3060"></span>
<span class="source-line-no">3061</span><span id="line-3061"> CheckAndMutateResult result = region.checkAndMutate(checkAndMutate);</span>
<span class="source-line-no">3062</span><span id="line-3062"> assertTrue(result.isSuccess());</span>
<span class="source-line-no">3063</span><span id="line-3063"> assertEquals(6L, Bytes.toLong(result.getResult().getValue(fam1, q3)));</span>
<span class="source-line-no">3064</span><span id="line-3064"> assertEquals("ab", Bytes.toString(result.getResult().getValue(fam1, q4)));</span>
<span class="source-line-no">3065</span><span id="line-3065"></span>
<span class="source-line-no">3066</span><span id="line-3066"> // Verify the value</span>
<span class="source-line-no">3067</span><span id="line-3067"> Result r = region.get(new Get(row));</span>
<span class="source-line-no">3068</span><span id="line-3068"> assertEquals(v1, Bytes.toString(r.getValue(fam1, q1)));</span>
<span class="source-line-no">3069</span><span id="line-3069"> assertNull(r.getValue(fam1, q2));</span>
<span class="source-line-no">3070</span><span id="line-3070"> assertEquals(6L, Bytes.toLong(r.getValue(fam1, q3)));</span>
<span class="source-line-no">3071</span><span id="line-3071"> assertEquals("ab", Bytes.toString(r.getValue(fam1, q4)));</span>
<span class="source-line-no">3072</span><span id="line-3072"></span>
<span class="source-line-no">3073</span><span id="line-3073"> // Do CheckAndRowMutations again</span>
<span class="source-line-no">3074</span><span id="line-3074"> checkAndMutate = CheckAndMutate.newBuilder(row).ifNotExists(fam1, q1)</span>
<span class="source-line-no">3075</span><span id="line-3075"> .build(new RowMutations(row).add(Arrays.asList(new Delete(row).addColumns(fam1, q1),</span>
<span class="source-line-no">3076</span><span id="line-3076"> new Put(row).addColumn(fam1, q2, Bytes.toBytes(v1)),</span>
<span class="source-line-no">3077</span><span id="line-3077"> new Increment(row).addColumn(fam1, q3, 1),</span>
<span class="source-line-no">3078</span><span id="line-3078"> new Append(row).addColumn(fam1, q4, Bytes.toBytes("b")))));</span>
<span class="source-line-no">3079</span><span id="line-3079"></span>
<span class="source-line-no">3080</span><span id="line-3080"> result = region.checkAndMutate(checkAndMutate);</span>
<span class="source-line-no">3081</span><span id="line-3081"> assertFalse(result.isSuccess());</span>
<span class="source-line-no">3082</span><span id="line-3082"> assertNull(result.getResult());</span>
<span class="source-line-no">3083</span><span id="line-3083"></span>
<span class="source-line-no">3084</span><span id="line-3084"> // Verify the value</span>
<span class="source-line-no">3085</span><span id="line-3085"> r = region.get(new Get(row));</span>
<span class="source-line-no">3086</span><span id="line-3086"> assertEquals(v1, Bytes.toString(r.getValue(fam1, q1)));</span>
<span class="source-line-no">3087</span><span id="line-3087"> assertNull(r.getValue(fam1, q2));</span>
<span class="source-line-no">3088</span><span id="line-3088"> assertEquals(6L, Bytes.toLong(r.getValue(fam1, q3)));</span>
<span class="source-line-no">3089</span><span id="line-3089"> assertEquals("ab", Bytes.toString(r.getValue(fam1, q4)));</span>
<span class="source-line-no">3090</span><span id="line-3090"> }</span>
<span class="source-line-no">3091</span><span id="line-3091"></span>
<span class="source-line-no">3092</span><span id="line-3092"> // ////////////////////////////////////////////////////////////////////////////</span>
<span class="source-line-no">3093</span><span id="line-3093"> // Delete tests</span>
<span class="source-line-no">3094</span><span id="line-3094"> // ////////////////////////////////////////////////////////////////////////////</span>
<span class="source-line-no">3095</span><span id="line-3095"> @Test</span>
<span class="source-line-no">3096</span><span id="line-3096"> public void testDelete_multiDeleteColumn() throws IOException {</span>
<span class="source-line-no">3097</span><span id="line-3097"> byte[] row1 = Bytes.toBytes("row1");</span>
<span class="source-line-no">3098</span><span id="line-3098"> byte[] fam1 = Bytes.toBytes("fam1");</span>
<span class="source-line-no">3099</span><span id="line-3099"> byte[] qual = Bytes.toBytes("qualifier");</span>
<span class="source-line-no">3100</span><span id="line-3100"> byte[] value = Bytes.toBytes("value");</span>
<span class="source-line-no">3101</span><span id="line-3101"></span>
<span class="source-line-no">3102</span><span id="line-3102"> Put put = new Put(row1);</span>
<span class="source-line-no">3103</span><span id="line-3103"> put.addColumn(fam1, qual, 1, value);</span>
<span class="source-line-no">3104</span><span id="line-3104"> put.addColumn(fam1, qual, 2, value);</span>
<span class="source-line-no">3105</span><span id="line-3105"></span>
<span class="source-line-no">3106</span><span id="line-3106"> this.region = initHRegion(tableName, method, CONF, fam1);</span>
<span class="source-line-no">3107</span><span id="line-3107"> region.put(put);</span>
<span class="source-line-no">3108</span><span id="line-3108"></span>
<span class="source-line-no">3109</span><span id="line-3109"> // We do support deleting more than 1 'latest' version</span>
<span class="source-line-no">3110</span><span id="line-3110"> Delete delete = new Delete(row1);</span>
<span class="source-line-no">3111</span><span id="line-3111"> delete.addColumn(fam1, qual);</span>
<span class="source-line-no">3112</span><span id="line-3112"> delete.addColumn(fam1, qual);</span>
<span class="source-line-no">3113</span><span id="line-3113"> region.delete(delete);</span>
<span class="source-line-no">3114</span><span id="line-3114"></span>
<span class="source-line-no">3115</span><span id="line-3115"> Get get = new Get(row1);</span>
<span class="source-line-no">3116</span><span id="line-3116"> get.addFamily(fam1);</span>
<span class="source-line-no">3117</span><span id="line-3117"> Result r = region.get(get);</span>
<span class="source-line-no">3118</span><span id="line-3118"> assertEquals(0, r.size());</span>
<span class="source-line-no">3119</span><span id="line-3119"> }</span>
<span class="source-line-no">3120</span><span id="line-3120"></span>
<span class="source-line-no">3121</span><span id="line-3121"> @Test</span>
<span class="source-line-no">3122</span><span id="line-3122"> public void testDelete_CheckFamily() throws IOException {</span>
<span class="source-line-no">3123</span><span id="line-3123"> byte[] row1 = Bytes.toBytes("row1");</span>
<span class="source-line-no">3124</span><span id="line-3124"> byte[] fam1 = Bytes.toBytes("fam1");</span>
<span class="source-line-no">3125</span><span id="line-3125"> byte[] fam2 = Bytes.toBytes("fam2");</span>
<span class="source-line-no">3126</span><span id="line-3126"> byte[] fam3 = Bytes.toBytes("fam3");</span>
<span class="source-line-no">3127</span><span id="line-3127"> byte[] fam4 = Bytes.toBytes("fam4");</span>
<span class="source-line-no">3128</span><span id="line-3128"></span>
<span class="source-line-no">3129</span><span id="line-3129"> // Setting up region</span>
<span class="source-line-no">3130</span><span id="line-3130"> this.region = initHRegion(tableName, method, CONF, fam1, fam2, fam3);</span>
<span class="source-line-no">3131</span><span id="line-3131"> List&lt;Cell&gt; kvs = new ArrayList&lt;&gt;();</span>
<span class="source-line-no">3132</span><span id="line-3132"> kvs.add(new KeyValue(row1, fam4, null, null));</span>
<span class="source-line-no">3133</span><span id="line-3133"></span>
<span class="source-line-no">3134</span><span id="line-3134"> byte[] forUnitTestsOnly = Bytes.toBytes("ForUnitTestsOnly");</span>
<span class="source-line-no">3135</span><span id="line-3135"></span>
<span class="source-line-no">3136</span><span id="line-3136"> // testing existing family</span>
<span class="source-line-no">3137</span><span id="line-3137"> NavigableMap&lt;byte[], List&lt;Cell&gt;&gt; deleteMap = new TreeMap&lt;&gt;(Bytes.BYTES_COMPARATOR);</span>
<span class="source-line-no">3138</span><span id="line-3138"> deleteMap.put(fam2, kvs);</span>
<span class="source-line-no">3139</span><span id="line-3139"> region.delete(new Delete(forUnitTestsOnly, HConstants.LATEST_TIMESTAMP, deleteMap));</span>
<span class="source-line-no">3140</span><span id="line-3140"></span>
<span class="source-line-no">3141</span><span id="line-3141"> // testing non existing family</span>
<span class="source-line-no">3142</span><span id="line-3142"> NavigableMap&lt;byte[], List&lt;Cell&gt;&gt; deleteMap2 = new TreeMap&lt;&gt;(Bytes.BYTES_COMPARATOR);</span>
<span class="source-line-no">3143</span><span id="line-3143"> deleteMap2.put(fam4, kvs);</span>
<span class="source-line-no">3144</span><span id="line-3144"> assertThrows("Family " + Bytes.toString(fam4) + " does exist",</span>
<span class="source-line-no">3145</span><span id="line-3145"> NoSuchColumnFamilyException.class,</span>
<span class="source-line-no">3146</span><span id="line-3146"> () -&gt; region.delete(new Delete(forUnitTestsOnly, HConstants.LATEST_TIMESTAMP, deleteMap2)));</span>
<span class="source-line-no">3147</span><span id="line-3147"> }</span>
<span class="source-line-no">3148</span><span id="line-3148"></span>
<span class="source-line-no">3149</span><span id="line-3149"> @Test</span>
<span class="source-line-no">3150</span><span id="line-3150"> public void testDelete_mixed() throws IOException, InterruptedException {</span>
<span class="source-line-no">3151</span><span id="line-3151"> byte[] fam = Bytes.toBytes("info");</span>
<span class="source-line-no">3152</span><span id="line-3152"> byte[][] families = { fam };</span>
<span class="source-line-no">3153</span><span id="line-3153"> this.region = initHRegion(tableName, method, CONF, families);</span>
<span class="source-line-no">3154</span><span id="line-3154"> EnvironmentEdgeManagerTestHelper.injectEdge(new IncrementingEnvironmentEdge());</span>
<span class="source-line-no">3155</span><span id="line-3155"></span>
<span class="source-line-no">3156</span><span id="line-3156"> byte[] row = Bytes.toBytes("table_name");</span>
<span class="source-line-no">3157</span><span id="line-3157"> // column names</span>
<span class="source-line-no">3158</span><span id="line-3158"> byte[] serverinfo = Bytes.toBytes("serverinfo");</span>
<span class="source-line-no">3159</span><span id="line-3159"> byte[] splitA = Bytes.toBytes("splitA");</span>
<span class="source-line-no">3160</span><span id="line-3160"> byte[] splitB = Bytes.toBytes("splitB");</span>
<span class="source-line-no">3161</span><span id="line-3161"></span>
<span class="source-line-no">3162</span><span id="line-3162"> // add some data:</span>
<span class="source-line-no">3163</span><span id="line-3163"> Put put = new Put(row);</span>
<span class="source-line-no">3164</span><span id="line-3164"> put.addColumn(fam, splitA, Bytes.toBytes("reference_A"));</span>
<span class="source-line-no">3165</span><span id="line-3165"> region.put(put);</span>
<span class="source-line-no">3166</span><span id="line-3166"></span>
<span class="source-line-no">3167</span><span id="line-3167"> put = new Put(row);</span>
<span class="source-line-no">3168</span><span id="line-3168"> put.addColumn(fam, splitB, Bytes.toBytes("reference_B"));</span>
<span class="source-line-no">3169</span><span id="line-3169"> region.put(put);</span>
<span class="source-line-no">3170</span><span id="line-3170"></span>
<span class="source-line-no">3171</span><span id="line-3171"> put = new Put(row);</span>
<span class="source-line-no">3172</span><span id="line-3172"> put.addColumn(fam, serverinfo, Bytes.toBytes("ip_address"));</span>
<span class="source-line-no">3173</span><span id="line-3173"> region.put(put);</span>
<span class="source-line-no">3174</span><span id="line-3174"></span>
<span class="source-line-no">3175</span><span id="line-3175"> // ok now delete a split:</span>
<span class="source-line-no">3176</span><span id="line-3176"> Delete delete = new Delete(row);</span>
<span class="source-line-no">3177</span><span id="line-3177"> delete.addColumns(fam, splitA);</span>
<span class="source-line-no">3178</span><span id="line-3178"> region.delete(delete);</span>
<span class="source-line-no">3179</span><span id="line-3179"></span>
<span class="source-line-no">3180</span><span id="line-3180"> // assert some things:</span>
<span class="source-line-no">3181</span><span id="line-3181"> Get get = new Get(row).addColumn(fam, serverinfo);</span>
<span class="source-line-no">3182</span><span id="line-3182"> Result result = region.get(get);</span>
<span class="source-line-no">3183</span><span id="line-3183"> assertEquals(1, result.size());</span>
<span class="source-line-no">3184</span><span id="line-3184"></span>
<span class="source-line-no">3185</span><span id="line-3185"> get = new Get(row).addColumn(fam, splitA);</span>
<span class="source-line-no">3186</span><span id="line-3186"> result = region.get(get);</span>
<span class="source-line-no">3187</span><span id="line-3187"> assertEquals(0, result.size());</span>
<span class="source-line-no">3188</span><span id="line-3188"></span>
<span class="source-line-no">3189</span><span id="line-3189"> get = new Get(row).addColumn(fam, splitB);</span>
<span class="source-line-no">3190</span><span id="line-3190"> result = region.get(get);</span>
<span class="source-line-no">3191</span><span id="line-3191"> assertEquals(1, result.size());</span>
<span class="source-line-no">3192</span><span id="line-3192"></span>
<span class="source-line-no">3193</span><span id="line-3193"> // Assert that after a delete, I can put.</span>
<span class="source-line-no">3194</span><span id="line-3194"> put = new Put(row);</span>
<span class="source-line-no">3195</span><span id="line-3195"> put.addColumn(fam, splitA, Bytes.toBytes("reference_A"));</span>
<span class="source-line-no">3196</span><span id="line-3196"> region.put(put);</span>
<span class="source-line-no">3197</span><span id="line-3197"> get = new Get(row);</span>
<span class="source-line-no">3198</span><span id="line-3198"> result = region.get(get);</span>
<span class="source-line-no">3199</span><span id="line-3199"> assertEquals(3, result.size());</span>
<span class="source-line-no">3200</span><span id="line-3200"></span>
<span class="source-line-no">3201</span><span id="line-3201"> // Now delete all... then test I can add stuff back</span>
<span class="source-line-no">3202</span><span id="line-3202"> delete = new Delete(row);</span>
<span class="source-line-no">3203</span><span id="line-3203"> region.delete(delete);</span>
<span class="source-line-no">3204</span><span id="line-3204"> assertEquals(0, region.get(get).size());</span>
<span class="source-line-no">3205</span><span id="line-3205"></span>
<span class="source-line-no">3206</span><span id="line-3206"> region.put(new Put(row).addColumn(fam, splitA, Bytes.toBytes("reference_A")));</span>
<span class="source-line-no">3207</span><span id="line-3207"> result = region.get(get);</span>
<span class="source-line-no">3208</span><span id="line-3208"> assertEquals(1, result.size());</span>
<span class="source-line-no">3209</span><span id="line-3209"> }</span>
<span class="source-line-no">3210</span><span id="line-3210"></span>
<span class="source-line-no">3211</span><span id="line-3211"> @Test</span>
<span class="source-line-no">3212</span><span id="line-3212"> public void testDeleteRowWithFutureTs() throws IOException {</span>
<span class="source-line-no">3213</span><span id="line-3213"> byte[] fam = Bytes.toBytes("info");</span>
<span class="source-line-no">3214</span><span id="line-3214"> byte[][] families = { fam };</span>
<span class="source-line-no">3215</span><span id="line-3215"> this.region = initHRegion(tableName, method, CONF, families);</span>
<span class="source-line-no">3216</span><span id="line-3216"> byte[] row = Bytes.toBytes("table_name");</span>
<span class="source-line-no">3217</span><span id="line-3217"> // column names</span>
<span class="source-line-no">3218</span><span id="line-3218"> byte[] serverinfo = Bytes.toBytes("serverinfo");</span>
<span class="source-line-no">3219</span><span id="line-3219"></span>
<span class="source-line-no">3220</span><span id="line-3220"> // add data in the far future</span>
<span class="source-line-no">3221</span><span id="line-3221"> Put put = new Put(row);</span>
<span class="source-line-no">3222</span><span id="line-3222"> put.addColumn(fam, serverinfo, HConstants.LATEST_TIMESTAMP - 5, Bytes.toBytes("value"));</span>
<span class="source-line-no">3223</span><span id="line-3223"> region.put(put);</span>
<span class="source-line-no">3224</span><span id="line-3224"></span>
<span class="source-line-no">3225</span><span id="line-3225"> // now delete something in the present</span>
<span class="source-line-no">3226</span><span id="line-3226"> Delete delete = new Delete(row);</span>
<span class="source-line-no">3227</span><span id="line-3227"> region.delete(delete);</span>
<span class="source-line-no">3228</span><span id="line-3228"></span>
<span class="source-line-no">3229</span><span id="line-3229"> // make sure we still see our data</span>
<span class="source-line-no">3230</span><span id="line-3230"> Get get = new Get(row).addColumn(fam, serverinfo);</span>
<span class="source-line-no">3231</span><span id="line-3231"> Result result = region.get(get);</span>
<span class="source-line-no">3232</span><span id="line-3232"> assertEquals(1, result.size());</span>
<span class="source-line-no">3233</span><span id="line-3233"></span>
<span class="source-line-no">3234</span><span id="line-3234"> // delete the future row</span>
<span class="source-line-no">3235</span><span id="line-3235"> delete = new Delete(row, HConstants.LATEST_TIMESTAMP - 3);</span>
<span class="source-line-no">3236</span><span id="line-3236"> region.delete(delete);</span>
<span class="source-line-no">3237</span><span id="line-3237"></span>
<span class="source-line-no">3238</span><span id="line-3238"> // make sure it is gone</span>
<span class="source-line-no">3239</span><span id="line-3239"> get = new Get(row).addColumn(fam, serverinfo);</span>
<span class="source-line-no">3240</span><span id="line-3240"> result = region.get(get);</span>
<span class="source-line-no">3241</span><span id="line-3241"> assertEquals(0, result.size());</span>
<span class="source-line-no">3242</span><span id="line-3242"> }</span>
<span class="source-line-no">3243</span><span id="line-3243"></span>
<span class="source-line-no">3244</span><span id="line-3244"> /**</span>
<span class="source-line-no">3245</span><span id="line-3245"> * Tests that the special LATEST_TIMESTAMP option for puts gets replaced by the actual timestamp</span>
<span class="source-line-no">3246</span><span id="line-3246"> */</span>
<span class="source-line-no">3247</span><span id="line-3247"> @Test</span>
<span class="source-line-no">3248</span><span id="line-3248"> public void testPutWithLatestTS() throws IOException {</span>
<span class="source-line-no">3249</span><span id="line-3249"> byte[] fam = Bytes.toBytes("info");</span>
<span class="source-line-no">3250</span><span id="line-3250"> byte[][] families = { fam };</span>
<span class="source-line-no">3251</span><span id="line-3251"> this.region = initHRegion(tableName, method, CONF, families);</span>
<span class="source-line-no">3252</span><span id="line-3252"> byte[] row = Bytes.toBytes("row1");</span>
<span class="source-line-no">3253</span><span id="line-3253"> // column names</span>
<span class="source-line-no">3254</span><span id="line-3254"> byte[] qual = Bytes.toBytes("qual");</span>
<span class="source-line-no">3255</span><span id="line-3255"></span>
<span class="source-line-no">3256</span><span id="line-3256"> // add data with LATEST_TIMESTAMP, put without WAL</span>
<span class="source-line-no">3257</span><span id="line-3257"> Put put = new Put(row);</span>
<span class="source-line-no">3258</span><span id="line-3258"> put.addColumn(fam, qual, HConstants.LATEST_TIMESTAMP, Bytes.toBytes("value"));</span>
<span class="source-line-no">3259</span><span id="line-3259"> region.put(put);</span>
<span class="source-line-no">3260</span><span id="line-3260"></span>
<span class="source-line-no">3261</span><span id="line-3261"> // Make sure it shows up with an actual timestamp</span>
<span class="source-line-no">3262</span><span id="line-3262"> Get get = new Get(row).addColumn(fam, qual);</span>
<span class="source-line-no">3263</span><span id="line-3263"> Result result = region.get(get);</span>
<span class="source-line-no">3264</span><span id="line-3264"> assertEquals(1, result.size());</span>
<span class="source-line-no">3265</span><span id="line-3265"> Cell kv = result.rawCells()[0];</span>
<span class="source-line-no">3266</span><span id="line-3266"> LOG.info("Got: " + kv);</span>
<span class="source-line-no">3267</span><span id="line-3267"> assertTrue("LATEST_TIMESTAMP was not replaced with real timestamp",</span>
<span class="source-line-no">3268</span><span id="line-3268"> kv.getTimestamp() != HConstants.LATEST_TIMESTAMP);</span>
<span class="source-line-no">3269</span><span id="line-3269"></span>
<span class="source-line-no">3270</span><span id="line-3270"> // Check same with WAL enabled (historically these took different</span>
<span class="source-line-no">3271</span><span id="line-3271"> // code paths, so check both)</span>
<span class="source-line-no">3272</span><span id="line-3272"> row = Bytes.toBytes("row2");</span>
<span class="source-line-no">3273</span><span id="line-3273"> put = new Put(row);</span>
<span class="source-line-no">3274</span><span id="line-3274"> put.addColumn(fam, qual, HConstants.LATEST_TIMESTAMP, Bytes.toBytes("value"));</span>
<span class="source-line-no">3275</span><span id="line-3275"> region.put(put);</span>
<span class="source-line-no">3276</span><span id="line-3276"></span>
<span class="source-line-no">3277</span><span id="line-3277"> // Make sure it shows up with an actual timestamp</span>
<span class="source-line-no">3278</span><span id="line-3278"> get = new Get(row).addColumn(fam, qual);</span>
<span class="source-line-no">3279</span><span id="line-3279"> result = region.get(get);</span>
<span class="source-line-no">3280</span><span id="line-3280"> assertEquals(1, result.size());</span>
<span class="source-line-no">3281</span><span id="line-3281"> kv = result.rawCells()[0];</span>
<span class="source-line-no">3282</span><span id="line-3282"> LOG.info("Got: " + kv);</span>
<span class="source-line-no">3283</span><span id="line-3283"> assertTrue("LATEST_TIMESTAMP was not replaced with real timestamp",</span>
<span class="source-line-no">3284</span><span id="line-3284"> kv.getTimestamp() != HConstants.LATEST_TIMESTAMP);</span>
<span class="source-line-no">3285</span><span id="line-3285"> }</span>
<span class="source-line-no">3286</span><span id="line-3286"></span>
<span class="source-line-no">3287</span><span id="line-3287"> /**</span>
<span class="source-line-no">3288</span><span id="line-3288"> * Tests that there is server-side filtering for invalid timestamp upper bound. Note that the</span>
<span class="source-line-no">3289</span><span id="line-3289"> * timestamp lower bound is automatically handled for us by the TTL field.</span>
<span class="source-line-no">3290</span><span id="line-3290"> */</span>
<span class="source-line-no">3291</span><span id="line-3291"> @Test</span>
<span class="source-line-no">3292</span><span id="line-3292"> public void testPutWithTsSlop() throws IOException {</span>
<span class="source-line-no">3293</span><span id="line-3293"> byte[] fam = Bytes.toBytes("info");</span>
<span class="source-line-no">3294</span><span id="line-3294"> byte[][] families = { fam };</span>
<span class="source-line-no">3295</span><span id="line-3295"></span>
<span class="source-line-no">3296</span><span id="line-3296"> // add data with a timestamp that is too recent for range. Ensure assert</span>
<span class="source-line-no">3297</span><span id="line-3297"> CONF.setInt("hbase.hregion.keyvalue.timestamp.slop.millisecs", 1000);</span>
<span class="source-line-no">3298</span><span id="line-3298"> this.region = initHRegion(tableName, method, CONF, families);</span>
<span class="source-line-no">3299</span><span id="line-3299"> boolean caughtExcep = false;</span>
<span class="source-line-no">3300</span><span id="line-3300"> try {</span>
<span class="source-line-no">3301</span><span id="line-3301"> // no TS specified == use latest. should not error</span>
<span class="source-line-no">3302</span><span id="line-3302"> region.put(new Put(row).addColumn(fam, Bytes.toBytes("qual"), Bytes.toBytes("value")));</span>
<span class="source-line-no">3303</span><span id="line-3303"> // TS out of range. should error</span>
<span class="source-line-no">3304</span><span id="line-3304"> region.put(new Put(row).addColumn(fam, Bytes.toBytes("qual"),</span>
<span class="source-line-no">3305</span><span id="line-3305"> EnvironmentEdgeManager.currentTime() + 2000, Bytes.toBytes("value")));</span>
<span class="source-line-no">3306</span><span id="line-3306"> fail("Expected IOE for TS out of configured timerange");</span>
<span class="source-line-no">3307</span><span id="line-3307"> } catch (FailedSanityCheckException ioe) {</span>
<span class="source-line-no">3308</span><span id="line-3308"> LOG.debug("Received expected exception", ioe);</span>
<span class="source-line-no">3309</span><span id="line-3309"> caughtExcep = true;</span>
<span class="source-line-no">3310</span><span id="line-3310"> }</span>
<span class="source-line-no">3311</span><span id="line-3311"> assertTrue("Should catch FailedSanityCheckException", caughtExcep);</span>
<span class="source-line-no">3312</span><span id="line-3312"> }</span>
<span class="source-line-no">3313</span><span id="line-3313"></span>
<span class="source-line-no">3314</span><span id="line-3314"> @Test</span>
<span class="source-line-no">3315</span><span id="line-3315"> public void testScanner_DeleteOneFamilyNotAnother() throws IOException {</span>
<span class="source-line-no">3316</span><span id="line-3316"> byte[] fam1 = Bytes.toBytes("columnA");</span>
<span class="source-line-no">3317</span><span id="line-3317"> byte[] fam2 = Bytes.toBytes("columnB");</span>
<span class="source-line-no">3318</span><span id="line-3318"> this.region = initHRegion(tableName, method, CONF, fam1, fam2);</span>
<span class="source-line-no">3319</span><span id="line-3319"> byte[] rowA = Bytes.toBytes("rowA");</span>
<span class="source-line-no">3320</span><span id="line-3320"> byte[] rowB = Bytes.toBytes("rowB");</span>
<span class="source-line-no">3321</span><span id="line-3321"></span>
<span class="source-line-no">3322</span><span id="line-3322"> byte[] value = Bytes.toBytes("value");</span>
<span class="source-line-no">3323</span><span id="line-3323"></span>
<span class="source-line-no">3324</span><span id="line-3324"> Delete delete = new Delete(rowA);</span>
<span class="source-line-no">3325</span><span id="line-3325"> delete.addFamily(fam1);</span>
<span class="source-line-no">3326</span><span id="line-3326"></span>
<span class="source-line-no">3327</span><span id="line-3327"> region.delete(delete);</span>
<span class="source-line-no">3328</span><span id="line-3328"></span>
<span class="source-line-no">3329</span><span id="line-3329"> // now create data.</span>
<span class="source-line-no">3330</span><span id="line-3330"> Put put = new Put(rowA);</span>
<span class="source-line-no">3331</span><span id="line-3331"> put.addColumn(fam2, null, value);</span>
<span class="source-line-no">3332</span><span id="line-3332"> region.put(put);</span>
<span class="source-line-no">3333</span><span id="line-3333"></span>
<span class="source-line-no">3334</span><span id="line-3334"> put = new Put(rowB);</span>
<span class="source-line-no">3335</span><span id="line-3335"> put.addColumn(fam1, null, value);</span>
<span class="source-line-no">3336</span><span id="line-3336"> put.addColumn(fam2, null, value);</span>
<span class="source-line-no">3337</span><span id="line-3337"> region.put(put);</span>
<span class="source-line-no">3338</span><span id="line-3338"></span>
<span class="source-line-no">3339</span><span id="line-3339"> Scan scan = new Scan();</span>
<span class="source-line-no">3340</span><span id="line-3340"> scan.addFamily(fam1).addFamily(fam2);</span>
<span class="source-line-no">3341</span><span id="line-3341"> try (InternalScanner s = region.getScanner(scan)) {</span>
<span class="source-line-no">3342</span><span id="line-3342"> List&lt;Cell&gt; results = new ArrayList&lt;&gt;();</span>
<span class="source-line-no">3343</span><span id="line-3343"> s.next(results);</span>
<span class="source-line-no">3344</span><span id="line-3344"> assertTrue(CellUtil.matchingRows(results.get(0), rowA));</span>
<span class="source-line-no">3345</span><span id="line-3345"></span>
<span class="source-line-no">3346</span><span id="line-3346"> results.clear();</span>
<span class="source-line-no">3347</span><span id="line-3347"> s.next(results);</span>
<span class="source-line-no">3348</span><span id="line-3348"> assertTrue(CellUtil.matchingRows(results.get(0), rowB));</span>
<span class="source-line-no">3349</span><span id="line-3349"> }</span>
<span class="source-line-no">3350</span><span id="line-3350"> }</span>
<span class="source-line-no">3351</span><span id="line-3351"></span>
<span class="source-line-no">3352</span><span id="line-3352"> @Test</span>
<span class="source-line-no">3353</span><span id="line-3353"> public void testDataInMemoryWithoutWAL() throws IOException {</span>
<span class="source-line-no">3354</span><span id="line-3354"> FileSystem fs = FileSystem.get(CONF);</span>
<span class="source-line-no">3355</span><span id="line-3355"> Path rootDir = new Path(dir + "testDataInMemoryWithoutWAL");</span>
<span class="source-line-no">3356</span><span id="line-3356"> FSHLog hLog = new FSHLog(fs, rootDir, "testDataInMemoryWithoutWAL", CONF);</span>
<span class="source-line-no">3357</span><span id="line-3357"> hLog.init();</span>
<span class="source-line-no">3358</span><span id="line-3358"> // This chunk creation is done throughout the code base. Do we want to move it into core?</span>
<span class="source-line-no">3359</span><span id="line-3359"> // It is missing from this test. W/o it we NPE.</span>
<span class="source-line-no">3360</span><span id="line-3360"> region = initHRegion(tableName, null, null, CONF, false, Durability.SYNC_WAL, hLog,</span>
<span class="source-line-no">3361</span><span id="line-3361"> COLUMN_FAMILY_BYTES);</span>
<span class="source-line-no">3362</span><span id="line-3362"></span>
<span class="source-line-no">3363</span><span id="line-3363"> Cell originalCell = ExtendedCellBuilderFactory.create(CellBuilderType.DEEP_COPY).setRow(row)</span>
<span class="source-line-no">3364</span><span id="line-3364"> .setFamily(COLUMN_FAMILY_BYTES).setQualifier(qual1)</span>
<span class="source-line-no">3365</span><span id="line-3365"> .setTimestamp(EnvironmentEdgeManager.currentTime()).setType(KeyValue.Type.Put.getCode())</span>
<span class="source-line-no">3366</span><span id="line-3366"> .setValue(value1).build();</span>
<span class="source-line-no">3367</span><span id="line-3367"> final long originalSize = originalCell.getSerializedSize();</span>
<span class="source-line-no">3368</span><span id="line-3368"></span>
<span class="source-line-no">3369</span><span id="line-3369"> Cell addCell = ExtendedCellBuilderFactory.create(CellBuilderType.DEEP_COPY).setRow(row)</span>
<span class="source-line-no">3370</span><span id="line-3370"> .setFamily(COLUMN_FAMILY_BYTES).setQualifier(qual1)</span>
<span class="source-line-no">3371</span><span id="line-3371"> .setTimestamp(EnvironmentEdgeManager.currentTime()).setType(KeyValue.Type.Put.getCode())</span>
<span class="source-line-no">3372</span><span id="line-3372"> .setValue(Bytes.toBytes("xxxxxxxxxx")).build();</span>
<span class="source-line-no">3373</span><span id="line-3373"> final long addSize = addCell.getSerializedSize();</span>
<span class="source-line-no">3374</span><span id="line-3374"></span>
<span class="source-line-no">3375</span><span id="line-3375"> LOG.info("originalSize:" + originalSize + ", addSize:" + addSize);</span>
<span class="source-line-no">3376</span><span id="line-3376"> // start test. We expect that the addPut's durability will be replaced</span>
<span class="source-line-no">3377</span><span id="line-3377"> // by originalPut's durability.</span>
<span class="source-line-no">3378</span><span id="line-3378"></span>
<span class="source-line-no">3379</span><span id="line-3379"> // case 1:</span>
<span class="source-line-no">3380</span><span id="line-3380"> testDataInMemoryWithoutWAL(region,</span>
<span class="source-line-no">3381</span><span id="line-3381"> new Put(row).add(originalCell).setDurability(Durability.SKIP_WAL),</span>
<span class="source-line-no">3382</span><span id="line-3382"> new Put(row).add(addCell).setDurability(Durability.SKIP_WAL), originalSize + addSize);</span>
<span class="source-line-no">3383</span><span id="line-3383"></span>
<span class="source-line-no">3384</span><span id="line-3384"> // case 2:</span>
<span class="source-line-no">3385</span><span id="line-3385"> testDataInMemoryWithoutWAL(region,</span>
<span class="source-line-no">3386</span><span id="line-3386"> new Put(row).add(originalCell).setDurability(Durability.SKIP_WAL),</span>
<span class="source-line-no">3387</span><span id="line-3387"> new Put(row).add(addCell).setDurability(Durability.SYNC_WAL), originalSize + addSize);</span>
<span class="source-line-no">3388</span><span id="line-3388"></span>
<span class="source-line-no">3389</span><span id="line-3389"> // case 3:</span>
<span class="source-line-no">3390</span><span id="line-3390"> testDataInMemoryWithoutWAL(region,</span>
<span class="source-line-no">3391</span><span id="line-3391"> new Put(row).add(originalCell).setDurability(Durability.SYNC_WAL),</span>
<span class="source-line-no">3392</span><span id="line-3392"> new Put(row).add(addCell).setDurability(Durability.SKIP_WAL), 0);</span>
<span class="source-line-no">3393</span><span id="line-3393"></span>
<span class="source-line-no">3394</span><span id="line-3394"> // case 4:</span>
<span class="source-line-no">3395</span><span id="line-3395"> testDataInMemoryWithoutWAL(region,</span>
<span class="source-line-no">3396</span><span id="line-3396"> new Put(row).add(originalCell).setDurability(Durability.SYNC_WAL),</span>
<span class="source-line-no">3397</span><span id="line-3397"> new Put(row).add(addCell).setDurability(Durability.SYNC_WAL), 0);</span>
<span class="source-line-no">3398</span><span id="line-3398"> }</span>
<span class="source-line-no">3399</span><span id="line-3399"></span>
<span class="source-line-no">3400</span><span id="line-3400"> private static void testDataInMemoryWithoutWAL(HRegion region, Put originalPut, final Put addPut,</span>
<span class="source-line-no">3401</span><span id="line-3401"> long delta) throws IOException {</span>
<span class="source-line-no">3402</span><span id="line-3402"> final long initSize = region.getDataInMemoryWithoutWAL();</span>
<span class="source-line-no">3403</span><span id="line-3403"> // save normalCPHost and replaced by mockedCPHost</span>
<span class="source-line-no">3404</span><span id="line-3404"> RegionCoprocessorHost normalCPHost = region.getCoprocessorHost();</span>
<span class="source-line-no">3405</span><span id="line-3405"> RegionCoprocessorHost mockedCPHost = mock(RegionCoprocessorHost.class);</span>
<span class="source-line-no">3406</span><span id="line-3406"> // Because the preBatchMutate returns void, we can't do usual Mockito when...then form. Must</span>
<span class="source-line-no">3407</span><span id="line-3407"> // do below format (from Mockito doc).</span>
<span class="source-line-no">3408</span><span id="line-3408"> doAnswer(new Answer&lt;Void&gt;() {</span>
<span class="source-line-no">3409</span><span id="line-3409"> @Override</span>
<span class="source-line-no">3410</span><span id="line-3410"> public Void answer(InvocationOnMock invocation) throws Throwable {</span>
<span class="source-line-no">3411</span><span id="line-3411"> MiniBatchOperationInProgress&lt;Mutation&gt; mb = invocation.getArgument(0);</span>
<span class="source-line-no">3412</span><span id="line-3412"> mb.addOperationsFromCP(0, new Mutation[] { addPut });</span>
<span class="source-line-no">3413</span><span id="line-3413"> return null;</span>
<span class="source-line-no">3414</span><span id="line-3414"> }</span>
<span class="source-line-no">3415</span><span id="line-3415"> }).when(mockedCPHost).preBatchMutate(isA(MiniBatchOperationInProgress.class));</span>
<span class="source-line-no">3416</span><span id="line-3416"> ColumnFamilyDescriptorBuilder builder =</span>
<span class="source-line-no">3417</span><span id="line-3417"> ColumnFamilyDescriptorBuilder.newBuilder(COLUMN_FAMILY_BYTES);</span>
<span class="source-line-no">3418</span><span id="line-3418"> ScanInfo info = new ScanInfo(CONF, builder.build(), Long.MAX_VALUE, Long.MAX_VALUE,</span>
<span class="source-line-no">3419</span><span id="line-3419"> region.getCellComparator());</span>
<span class="source-line-no">3420</span><span id="line-3420"> when(mockedCPHost.preFlushScannerOpen(any(HStore.class), any())).thenReturn(info);</span>
<span class="source-line-no">3421</span><span id="line-3421"></span>
<span class="source-line-no">3422</span><span id="line-3422"> when(mockedCPHost.preFlush(any(), any(StoreScanner.class), any()))</span>
<span class="source-line-no">3423</span><span id="line-3423"> .thenAnswer(i -&gt; i.getArgument(1));</span>
<span class="source-line-no">3424</span><span id="line-3424"> region.setCoprocessorHost(mockedCPHost);</span>
<span class="source-line-no">3425</span><span id="line-3425"></span>
<span class="source-line-no">3426</span><span id="line-3426"> region.put(originalPut);</span>
<span class="source-line-no">3427</span><span id="line-3427"> region.setCoprocessorHost(normalCPHost);</span>
<span class="source-line-no">3428</span><span id="line-3428"> final long finalSize = region.getDataInMemoryWithoutWAL();</span>
<span class="source-line-no">3429</span><span id="line-3429"> assertEquals("finalSize:" + finalSize + ", initSize:" + initSize + ", delta:" + delta,</span>
<span class="source-line-no">3430</span><span id="line-3430"> finalSize, initSize + delta);</span>
<span class="source-line-no">3431</span><span id="line-3431"> }</span>
<span class="source-line-no">3432</span><span id="line-3432"></span>
<span class="source-line-no">3433</span><span id="line-3433"> @Test</span>
<span class="source-line-no">3434</span><span id="line-3434"> public void testDeleteColumns_PostInsert() throws IOException, InterruptedException {</span>
<span class="source-line-no">3435</span><span id="line-3435"> Delete delete = new Delete(row);</span>
<span class="source-line-no">3436</span><span id="line-3436"> delete.addColumns(fam1, qual1);</span>
<span class="source-line-no">3437</span><span id="line-3437"> doTestDelete_AndPostInsert(delete);</span>
<span class="source-line-no">3438</span><span id="line-3438"> }</span>
<span class="source-line-no">3439</span><span id="line-3439"></span>
<span class="source-line-no">3440</span><span id="line-3440"> @Test</span>
<span class="source-line-no">3441</span><span id="line-3441"> public void testaddFamily_PostInsert() throws IOException, InterruptedException {</span>
<span class="source-line-no">3442</span><span id="line-3442"> Delete delete = new Delete(row);</span>
<span class="source-line-no">3443</span><span id="line-3443"> delete.addFamily(fam1);</span>
<span class="source-line-no">3444</span><span id="line-3444"> doTestDelete_AndPostInsert(delete);</span>
<span class="source-line-no">3445</span><span id="line-3445"> }</span>
<span class="source-line-no">3446</span><span id="line-3446"></span>
<span class="source-line-no">3447</span><span id="line-3447"> public void doTestDelete_AndPostInsert(Delete delete) throws IOException, InterruptedException {</span>
<span class="source-line-no">3448</span><span id="line-3448"> this.region = initHRegion(tableName, method, CONF, fam1);</span>
<span class="source-line-no">3449</span><span id="line-3449"> EnvironmentEdgeManagerTestHelper.injectEdge(new IncrementingEnvironmentEdge());</span>
<span class="source-line-no">3450</span><span id="line-3450"> Put put = new Put(row);</span>
<span class="source-line-no">3451</span><span id="line-3451"> put.addColumn(fam1, qual1, value1);</span>
<span class="source-line-no">3452</span><span id="line-3452"> region.put(put);</span>
<span class="source-line-no">3453</span><span id="line-3453"></span>
<span class="source-line-no">3454</span><span id="line-3454"> // now delete the value:</span>
<span class="source-line-no">3455</span><span id="line-3455"> region.delete(delete);</span>
<span class="source-line-no">3456</span><span id="line-3456"></span>
<span class="source-line-no">3457</span><span id="line-3457"> // ok put data:</span>
<span class="source-line-no">3458</span><span id="line-3458"> put = new Put(row);</span>
<span class="source-line-no">3459</span><span id="line-3459"> put.addColumn(fam1, qual1, value2);</span>
<span class="source-line-no">3460</span><span id="line-3460"> region.put(put);</span>
<span class="source-line-no">3461</span><span id="line-3461"></span>
<span class="source-line-no">3462</span><span id="line-3462"> // ok get:</span>
<span class="source-line-no">3463</span><span id="line-3463"> Get get = new Get(row);</span>
<span class="source-line-no">3464</span><span id="line-3464"> get.addColumn(fam1, qual1);</span>
<span class="source-line-no">3465</span><span id="line-3465"></span>
<span class="source-line-no">3466</span><span id="line-3466"> Result r = region.get(get);</span>
<span class="source-line-no">3467</span><span id="line-3467"> assertEquals(1, r.size());</span>
<span class="source-line-no">3468</span><span id="line-3468"> assertArrayEquals(value2, r.getValue(fam1, qual1));</span>
<span class="source-line-no">3469</span><span id="line-3469"></span>
<span class="source-line-no">3470</span><span id="line-3470"> // next:</span>
<span class="source-line-no">3471</span><span id="line-3471"> Scan scan = new Scan().withStartRow(row);</span>
<span class="source-line-no">3472</span><span id="line-3472"> scan.addColumn(fam1, qual1);</span>
<span class="source-line-no">3473</span><span id="line-3473"> try (InternalScanner s = region.getScanner(scan)) {</span>
<span class="source-line-no">3474</span><span id="line-3474"> List&lt;Cell&gt; results = new ArrayList&lt;&gt;();</span>
<span class="source-line-no">3475</span><span id="line-3475"> assertEquals(false, s.next(results));</span>
<span class="source-line-no">3476</span><span id="line-3476"> assertEquals(1, results.size());</span>
<span class="source-line-no">3477</span><span id="line-3477"> Cell kv = results.get(0);</span>
<span class="source-line-no">3478</span><span id="line-3478"></span>
<span class="source-line-no">3479</span><span id="line-3479"> assertArrayEquals(value2, CellUtil.cloneValue(kv));</span>
<span class="source-line-no">3480</span><span id="line-3480"> assertArrayEquals(fam1, CellUtil.cloneFamily(kv));</span>
<span class="source-line-no">3481</span><span id="line-3481"> assertArrayEquals(qual1, CellUtil.cloneQualifier(kv));</span>
<span class="source-line-no">3482</span><span id="line-3482"> assertArrayEquals(row, CellUtil.cloneRow(kv));</span>
<span class="source-line-no">3483</span><span id="line-3483"> }</span>
<span class="source-line-no">3484</span><span id="line-3484"> }</span>
<span class="source-line-no">3485</span><span id="line-3485"></span>
<span class="source-line-no">3486</span><span id="line-3486"> @Test</span>
<span class="source-line-no">3487</span><span id="line-3487"> public void testDelete_CheckTimestampUpdated() throws IOException {</span>
<span class="source-line-no">3488</span><span id="line-3488"> byte[] row1 = Bytes.toBytes("row1");</span>
<span class="source-line-no">3489</span><span id="line-3489"> byte[] col1 = Bytes.toBytes("col1");</span>
<span class="source-line-no">3490</span><span id="line-3490"> byte[] col2 = Bytes.toBytes("col2");</span>
<span class="source-line-no">3491</span><span id="line-3491"> byte[] col3 = Bytes.toBytes("col3");</span>
<span class="source-line-no">3492</span><span id="line-3492"></span>
<span class="source-line-no">3493</span><span id="line-3493"> byte[] forUnitTestsOnly = Bytes.toBytes("ForUnitTestsOnly");</span>
<span class="source-line-no">3494</span><span id="line-3494"></span>
<span class="source-line-no">3495</span><span id="line-3495"> // Setting up region</span>
<span class="source-line-no">3496</span><span id="line-3496"> this.region = initHRegion(tableName, method, CONF, fam1);</span>
<span class="source-line-no">3497</span><span id="line-3497"> // Building checkerList</span>
<span class="source-line-no">3498</span><span id="line-3498"> List&lt;Cell&gt; kvs = new ArrayList&lt;&gt;();</span>
<span class="source-line-no">3499</span><span id="line-3499"> kvs.add(new KeyValue(row1, fam1, col1, null));</span>
<span class="source-line-no">3500</span><span id="line-3500"> kvs.add(new KeyValue(row1, fam1, col2, null));</span>
<span class="source-line-no">3501</span><span id="line-3501"> kvs.add(new KeyValue(row1, fam1, col3, null));</span>
<span class="source-line-no">3502</span><span id="line-3502"></span>
<span class="source-line-no">3503</span><span id="line-3503"> NavigableMap&lt;byte[], List&lt;Cell&gt;&gt; deleteMap = new TreeMap&lt;&gt;(Bytes.BYTES_COMPARATOR);</span>
<span class="source-line-no">3504</span><span id="line-3504"> deleteMap.put(fam1, kvs);</span>
<span class="source-line-no">3505</span><span id="line-3505"> region.delete(new Delete(forUnitTestsOnly, HConstants.LATEST_TIMESTAMP, deleteMap));</span>
<span class="source-line-no">3506</span><span id="line-3506"></span>
<span class="source-line-no">3507</span><span id="line-3507"> // extract the key values out the memstore:</span>
<span class="source-line-no">3508</span><span id="line-3508"> // This is kinda hacky, but better than nothing...</span>
<span class="source-line-no">3509</span><span id="line-3509"> long now = EnvironmentEdgeManager.currentTime();</span>
<span class="source-line-no">3510</span><span id="line-3510"> AbstractMemStore memstore = (AbstractMemStore) region.getStore(fam1).memstore;</span>
<span class="source-line-no">3511</span><span id="line-3511"> Cell firstCell = memstore.getActive().first();</span>
<span class="source-line-no">3512</span><span id="line-3512"> assertTrue(firstCell.getTimestamp() &lt;= now);</span>
<span class="source-line-no">3513</span><span id="line-3513"> now = firstCell.getTimestamp();</span>
<span class="source-line-no">3514</span><span id="line-3514"> for (Cell cell : memstore.getActive().getCellSet()) {</span>
<span class="source-line-no">3515</span><span id="line-3515"> assertTrue(cell.getTimestamp() &lt;= now);</span>
<span class="source-line-no">3516</span><span id="line-3516"> now = cell.getTimestamp();</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"></span>
<span class="source-line-no">3520</span><span id="line-3520"> // ////////////////////////////////////////////////////////////////////////////</span>
<span class="source-line-no">3521</span><span id="line-3521"> // Get tests</span>
<span class="source-line-no">3522</span><span id="line-3522"> // ////////////////////////////////////////////////////////////////////////////</span>
<span class="source-line-no">3523</span><span id="line-3523"> @Test</span>
<span class="source-line-no">3524</span><span id="line-3524"> public void testGet_FamilyChecker() throws IOException {</span>
<span class="source-line-no">3525</span><span id="line-3525"> byte[] row1 = Bytes.toBytes("row1");</span>
<span class="source-line-no">3526</span><span id="line-3526"> byte[] fam1 = Bytes.toBytes("fam1");</span>
<span class="source-line-no">3527</span><span id="line-3527"> byte[] fam2 = Bytes.toBytes("False");</span>
<span class="source-line-no">3528</span><span id="line-3528"> byte[] col1 = Bytes.toBytes("col1");</span>
<span class="source-line-no">3529</span><span id="line-3529"></span>
<span class="source-line-no">3530</span><span id="line-3530"> // Setting up region</span>
<span class="source-line-no">3531</span><span id="line-3531"> this.region = initHRegion(tableName, method, CONF, fam1);</span>
<span class="source-line-no">3532</span><span id="line-3532"> Get get = new Get(row1);</span>
<span class="source-line-no">3533</span><span id="line-3533"> get.addColumn(fam2, col1);</span>
<span class="source-line-no">3534</span><span id="line-3534"></span>
<span class="source-line-no">3535</span><span id="line-3535"> // Test</span>
<span class="source-line-no">3536</span><span id="line-3536"> try {</span>
<span class="source-line-no">3537</span><span id="line-3537"> region.get(get);</span>
<span class="source-line-no">3538</span><span id="line-3538"> fail("Expecting DoNotRetryIOException in get but did not get any");</span>
<span class="source-line-no">3539</span><span id="line-3539"> } catch (org.apache.hadoop.hbase.DoNotRetryIOException e) {</span>
<span class="source-line-no">3540</span><span id="line-3540"> LOG.info("Got expected DoNotRetryIOException successfully");</span>
<span class="source-line-no">3541</span><span id="line-3541"> }</span>
<span class="source-line-no">3542</span><span id="line-3542"> }</span>
<span class="source-line-no">3543</span><span id="line-3543"></span>
<span class="source-line-no">3544</span><span id="line-3544"> @Test</span>
<span class="source-line-no">3545</span><span id="line-3545"> public void testGet_Basic() throws IOException {</span>
<span class="source-line-no">3546</span><span id="line-3546"> byte[] row1 = Bytes.toBytes("row1");</span>
<span class="source-line-no">3547</span><span id="line-3547"> byte[] fam1 = Bytes.toBytes("fam1");</span>
<span class="source-line-no">3548</span><span id="line-3548"> byte[] col1 = Bytes.toBytes("col1");</span>
<span class="source-line-no">3549</span><span id="line-3549"> byte[] col2 = Bytes.toBytes("col2");</span>
<span class="source-line-no">3550</span><span id="line-3550"> byte[] col3 = Bytes.toBytes("col3");</span>
<span class="source-line-no">3551</span><span id="line-3551"> byte[] col4 = Bytes.toBytes("col4");</span>
<span class="source-line-no">3552</span><span id="line-3552"> byte[] col5 = Bytes.toBytes("col5");</span>
<span class="source-line-no">3553</span><span id="line-3553"></span>
<span class="source-line-no">3554</span><span id="line-3554"> // Setting up region</span>
<span class="source-line-no">3555</span><span id="line-3555"> this.region = initHRegion(tableName, method, CONF, fam1);</span>
<span class="source-line-no">3556</span><span id="line-3556"> // Add to memstore</span>
<span class="source-line-no">3557</span><span id="line-3557"> Put put = new Put(row1);</span>
<span class="source-line-no">3558</span><span id="line-3558"> put.addColumn(fam1, col1, null);</span>
<span class="source-line-no">3559</span><span id="line-3559"> put.addColumn(fam1, col2, null);</span>
<span class="source-line-no">3560</span><span id="line-3560"> put.addColumn(fam1, col3, null);</span>
<span class="source-line-no">3561</span><span id="line-3561"> put.addColumn(fam1, col4, null);</span>
<span class="source-line-no">3562</span><span id="line-3562"> put.addColumn(fam1, col5, null);</span>
<span class="source-line-no">3563</span><span id="line-3563"> region.put(put);</span>
<span class="source-line-no">3564</span><span id="line-3564"></span>
<span class="source-line-no">3565</span><span id="line-3565"> Get get = new Get(row1);</span>
<span class="source-line-no">3566</span><span id="line-3566"> get.addColumn(fam1, col2);</span>
<span class="source-line-no">3567</span><span id="line-3567"> get.addColumn(fam1, col4);</span>
<span class="source-line-no">3568</span><span id="line-3568"> // Expected result</span>
<span class="source-line-no">3569</span><span id="line-3569"> KeyValue kv1 = new KeyValue(row1, fam1, col2);</span>
<span class="source-line-no">3570</span><span id="line-3570"> KeyValue kv2 = new KeyValue(row1, fam1, col4);</span>
<span class="source-line-no">3571</span><span id="line-3571"> KeyValue[] expected = { kv1, kv2 };</span>
<span class="source-line-no">3572</span><span id="line-3572"></span>
<span class="source-line-no">3573</span><span id="line-3573"> // Test</span>
<span class="source-line-no">3574</span><span id="line-3574"> Result res = region.get(get);</span>
<span class="source-line-no">3575</span><span id="line-3575"> assertEquals(expected.length, res.size());</span>
<span class="source-line-no">3576</span><span id="line-3576"> for (int i = 0; i &lt; res.size(); i++) {</span>
<span class="source-line-no">3577</span><span id="line-3577"> assertTrue(CellUtil.matchingRows(expected[i], res.rawCells()[i]));</span>
<span class="source-line-no">3578</span><span id="line-3578"> assertTrue(CellUtil.matchingFamily(expected[i], res.rawCells()[i]));</span>
<span class="source-line-no">3579</span><span id="line-3579"> assertTrue(CellUtil.matchingQualifier(expected[i], res.rawCells()[i]));</span>
<span class="source-line-no">3580</span><span id="line-3580"> }</span>
<span class="source-line-no">3581</span><span id="line-3581"></span>
<span class="source-line-no">3582</span><span id="line-3582"> // Test using a filter on a Get</span>
<span class="source-line-no">3583</span><span id="line-3583"> Get g = new Get(row1);</span>
<span class="source-line-no">3584</span><span id="line-3584"> final int count = 2;</span>
<span class="source-line-no">3585</span><span id="line-3585"> g.setFilter(new ColumnCountGetFilter(count));</span>
<span class="source-line-no">3586</span><span id="line-3586"> res = region.get(g);</span>
<span class="source-line-no">3587</span><span id="line-3587"> assertEquals(count, res.size());</span>
<span class="source-line-no">3588</span><span id="line-3588"> }</span>
<span class="source-line-no">3589</span><span id="line-3589"></span>
<span class="source-line-no">3590</span><span id="line-3590"> @Test</span>
<span class="source-line-no">3591</span><span id="line-3591"> public void testGet_Empty() throws IOException {</span>
<span class="source-line-no">3592</span><span id="line-3592"> byte[] row = Bytes.toBytes("row");</span>
<span class="source-line-no">3593</span><span id="line-3593"> byte[] fam = Bytes.toBytes("fam");</span>
<span class="source-line-no">3594</span><span id="line-3594"></span>
<span class="source-line-no">3595</span><span id="line-3595"> this.region = initHRegion(tableName, method, CONF, fam);</span>
<span class="source-line-no">3596</span><span id="line-3596"> Get get = new Get(row);</span>
<span class="source-line-no">3597</span><span id="line-3597"> get.addFamily(fam);</span>
<span class="source-line-no">3598</span><span id="line-3598"> Result r = region.get(get);</span>
<span class="source-line-no">3599</span><span id="line-3599"></span>
<span class="source-line-no">3600</span><span id="line-3600"> assertTrue(r.isEmpty());</span>
<span class="source-line-no">3601</span><span id="line-3601"> }</span>
<span class="source-line-no">3602</span><span id="line-3602"></span>
<span class="source-line-no">3603</span><span id="line-3603"> @Test</span>
<span class="source-line-no">3604</span><span id="line-3604"> public void testGetWithFilter() throws IOException, InterruptedException {</span>
<span class="source-line-no">3605</span><span id="line-3605"> byte[] row1 = Bytes.toBytes("row1");</span>
<span class="source-line-no">3606</span><span id="line-3606"> byte[] fam1 = Bytes.toBytes("fam1");</span>
<span class="source-line-no">3607</span><span id="line-3607"> byte[] col1 = Bytes.toBytes("col1");</span>
<span class="source-line-no">3608</span><span id="line-3608"> byte[] value1 = Bytes.toBytes("value1");</span>
<span class="source-line-no">3609</span><span id="line-3609"> byte[] value2 = Bytes.toBytes("value2");</span>
<span class="source-line-no">3610</span><span id="line-3610"></span>
<span class="source-line-no">3611</span><span id="line-3611"> final int maxVersions = 3;</span>
<span class="source-line-no">3612</span><span id="line-3612"> TableDescriptor tableDescriptor =</span>
<span class="source-line-no">3613</span><span id="line-3613"> TableDescriptorBuilder.newBuilder(TableName.valueOf("testFilterAndColumnTracker"))</span>
<span class="source-line-no">3614</span><span id="line-3614"> .setColumnFamily(</span>
<span class="source-line-no">3615</span><span id="line-3615"> ColumnFamilyDescriptorBuilder.newBuilder(fam1).setMaxVersions(maxVersions).build())</span>
<span class="source-line-no">3616</span><span id="line-3616"> .build();</span>
<span class="source-line-no">3617</span><span id="line-3617"> ChunkCreator.initialize(MemStoreLAB.CHUNK_SIZE_DEFAULT, false, 0, 0, 0, null,</span>
<span class="source-line-no">3618</span><span id="line-3618"> MemStoreLAB.INDEX_CHUNK_SIZE_PERCENTAGE_DEFAULT);</span>
<span class="source-line-no">3619</span><span id="line-3619"> RegionInfo info = RegionInfoBuilder.newBuilder(tableDescriptor.getTableName()).build();</span>
<span class="source-line-no">3620</span><span id="line-3620"> Path logDir = TEST_UTIL.getDataTestDirOnTestFS(method + ".log");</span>
<span class="source-line-no">3621</span><span id="line-3621"> final WAL wal = HBaseTestingUtil.createWal(TEST_UTIL.getConfiguration(), logDir, info);</span>
<span class="source-line-no">3622</span><span id="line-3622"> this.region = TEST_UTIL.createLocalHRegion(info, CONF, tableDescriptor, wal);</span>
<span class="source-line-no">3623</span><span id="line-3623"></span>
<span class="source-line-no">3624</span><span id="line-3624"> // Put 4 version to memstore</span>
<span class="source-line-no">3625</span><span id="line-3625"> long ts = 0;</span>
<span class="source-line-no">3626</span><span id="line-3626"> Put put = new Put(row1, ts);</span>
<span class="source-line-no">3627</span><span id="line-3627"> put.addColumn(fam1, col1, value1);</span>
<span class="source-line-no">3628</span><span id="line-3628"> region.put(put);</span>
<span class="source-line-no">3629</span><span id="line-3629"> put = new Put(row1, ts + 1);</span>
<span class="source-line-no">3630</span><span id="line-3630"> put.addColumn(fam1, col1, Bytes.toBytes("filter1"));</span>
<span class="source-line-no">3631</span><span id="line-3631"> region.put(put);</span>
<span class="source-line-no">3632</span><span id="line-3632"> put = new Put(row1, ts + 2);</span>
<span class="source-line-no">3633</span><span id="line-3633"> put.addColumn(fam1, col1, Bytes.toBytes("filter2"));</span>
<span class="source-line-no">3634</span><span id="line-3634"> region.put(put);</span>
<span class="source-line-no">3635</span><span id="line-3635"> put = new Put(row1, ts + 3);</span>
<span class="source-line-no">3636</span><span id="line-3636"> put.addColumn(fam1, col1, value2);</span>
<span class="source-line-no">3637</span><span id="line-3637"> region.put(put);</span>
<span class="source-line-no">3638</span><span id="line-3638"></span>
<span class="source-line-no">3639</span><span id="line-3639"> Get get = new Get(row1);</span>
<span class="source-line-no">3640</span><span id="line-3640"> get.readAllVersions();</span>
<span class="source-line-no">3641</span><span id="line-3641"> Result res = region.get(get);</span>
<span class="source-line-no">3642</span><span id="line-3642"> // Get 3 versions, the oldest version has gone from user view</span>
<span class="source-line-no">3643</span><span id="line-3643"> assertEquals(maxVersions, res.size());</span>
<span class="source-line-no">3644</span><span id="line-3644"></span>
<span class="source-line-no">3645</span><span id="line-3645"> get.setFilter(new ValueFilter(CompareOperator.EQUAL, new SubstringComparator("value")));</span>
<span class="source-line-no">3646</span><span id="line-3646"> res = region.get(get);</span>
<span class="source-line-no">3647</span><span id="line-3647"> // When use value filter, the oldest version should still gone from user view and it</span>
<span class="source-line-no">3648</span><span id="line-3648"> // should only return one key vaule</span>
<span class="source-line-no">3649</span><span id="line-3649"> assertEquals(1, res.size());</span>
<span class="source-line-no">3650</span><span id="line-3650"> assertTrue(CellUtil.matchingValue(new KeyValue(row1, fam1, col1, value2), res.rawCells()[0]));</span>
<span class="source-line-no">3651</span><span id="line-3651"> assertEquals(ts + 3, res.rawCells()[0].getTimestamp());</span>
<span class="source-line-no">3652</span><span id="line-3652"></span>
<span class="source-line-no">3653</span><span id="line-3653"> region.flush(true);</span>
<span class="source-line-no">3654</span><span id="line-3654"> region.compact(true);</span>
<span class="source-line-no">3655</span><span id="line-3655"> Thread.sleep(1000);</span>
<span class="source-line-no">3656</span><span id="line-3656"> res = region.get(get);</span>
<span class="source-line-no">3657</span><span id="line-3657"> // After flush and compact, the result should be consistent with previous result</span>
<span class="source-line-no">3658</span><span id="line-3658"> assertEquals(1, res.size());</span>
<span class="source-line-no">3659</span><span id="line-3659"> assertTrue(CellUtil.matchingValue(new KeyValue(row1, fam1, col1, value2), res.rawCells()[0]));</span>
<span class="source-line-no">3660</span><span id="line-3660"> }</span>
<span class="source-line-no">3661</span><span id="line-3661"></span>
<span class="source-line-no">3662</span><span id="line-3662"> // ////////////////////////////////////////////////////////////////////////////</span>
<span class="source-line-no">3663</span><span id="line-3663"> // Scanner tests</span>
<span class="source-line-no">3664</span><span id="line-3664"> // ////////////////////////////////////////////////////////////////////////////</span>
<span class="source-line-no">3665</span><span id="line-3665"> @Test</span>
<span class="source-line-no">3666</span><span id="line-3666"> public void testGetScanner_WithOkFamilies() throws IOException {</span>
<span class="source-line-no">3667</span><span id="line-3667"> byte[] fam1 = Bytes.toBytes("fam1");</span>
<span class="source-line-no">3668</span><span id="line-3668"> byte[] fam2 = Bytes.toBytes("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"> byte[][] families = { fam1, fam2 };</span>
<span class="source-line-no">3671</span><span id="line-3671"></span>
<span class="source-line-no">3672</span><span id="line-3672"> // Setting up region</span>
<span class="source-line-no">3673</span><span id="line-3673"> this.region = initHRegion(tableName, method, CONF, families);</span>
<span class="source-line-no">3674</span><span id="line-3674"> Scan scan = new Scan();</span>
<span class="source-line-no">3675</span><span id="line-3675"> scan.addFamily(fam1);</span>
<span class="source-line-no">3676</span><span id="line-3676"> scan.addFamily(fam2);</span>
<span class="source-line-no">3677</span><span id="line-3677"> region.getScanner(scan).close();</span>
<span class="source-line-no">3678</span><span id="line-3678"> }</span>
<span class="source-line-no">3679</span><span id="line-3679"></span>
<span class="source-line-no">3680</span><span id="line-3680"> @Test</span>
<span class="source-line-no">3681</span><span id="line-3681"> public void testGetScanner_WithNotOkFamilies() throws IOException {</span>
<span class="source-line-no">3682</span><span id="line-3682"> byte[] fam1 = Bytes.toBytes("fam1");</span>
<span class="source-line-no">3683</span><span id="line-3683"> byte[] fam2 = Bytes.toBytes("fam2");</span>
<span class="source-line-no">3684</span><span id="line-3684"></span>
<span class="source-line-no">3685</span><span id="line-3685"> byte[][] families = { fam1 };</span>
<span class="source-line-no">3686</span><span id="line-3686"></span>
<span class="source-line-no">3687</span><span id="line-3687"> // Setting up region</span>
<span class="source-line-no">3688</span><span id="line-3688"> this.region = initHRegion(tableName, method, CONF, families);</span>
<span class="source-line-no">3689</span><span id="line-3689"> Scan scan = new Scan();</span>
<span class="source-line-no">3690</span><span id="line-3690"> scan.addFamily(fam2);</span>
<span class="source-line-no">3691</span><span id="line-3691"> assertThrows(NoSuchColumnFamilyException.class, () -&gt; region.getScanner(scan));</span>
<span class="source-line-no">3692</span><span id="line-3692"> }</span>
<span class="source-line-no">3693</span><span id="line-3693"></span>
<span class="source-line-no">3694</span><span id="line-3694"> @Test</span>
<span class="source-line-no">3695</span><span id="line-3695"> public void testGetScanner_WithNoFamilies() throws IOException {</span>
<span class="source-line-no">3696</span><span id="line-3696"> byte[] row1 = Bytes.toBytes("row1");</span>
<span class="source-line-no">3697</span><span id="line-3697"> byte[] fam1 = Bytes.toBytes("fam1");</span>
<span class="source-line-no">3698</span><span id="line-3698"> byte[] fam2 = Bytes.toBytes("fam2");</span>
<span class="source-line-no">3699</span><span id="line-3699"> byte[] fam3 = Bytes.toBytes("fam3");</span>
<span class="source-line-no">3700</span><span id="line-3700"> byte[] fam4 = Bytes.toBytes("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"> byte[][] families = { fam1, fam2, fam3, fam4 };</span>
<span class="source-line-no">3703</span><span id="line-3703"></span>
<span class="source-line-no">3704</span><span id="line-3704"> // Setting up region</span>
<span class="source-line-no">3705</span><span id="line-3705"> this.region = initHRegion(tableName, method, CONF, families);</span>
<span class="source-line-no">3706</span><span id="line-3706"> // Putting data in Region</span>
<span class="source-line-no">3707</span><span id="line-3707"> Put put = new Put(row1);</span>
<span class="source-line-no">3708</span><span id="line-3708"> put.addColumn(fam1, null, null);</span>
<span class="source-line-no">3709</span><span id="line-3709"> put.addColumn(fam2, null, null);</span>
<span class="source-line-no">3710</span><span id="line-3710"> put.addColumn(fam3, null, null);</span>
<span class="source-line-no">3711</span><span id="line-3711"> put.addColumn(fam4, null, null);</span>
<span class="source-line-no">3712</span><span id="line-3712"> region.put(put);</span>
<span class="source-line-no">3713</span><span id="line-3713"></span>
<span class="source-line-no">3714</span><span id="line-3714"> Scan scan = null;</span>
<span class="source-line-no">3715</span><span id="line-3715"></span>
<span class="source-line-no">3716</span><span id="line-3716"> // Testing to see how many scanners that is produced by getScanner, starting with known number,</span>
<span class="source-line-no">3717</span><span id="line-3717"> // 2 - current = 1</span>
<span class="source-line-no">3718</span><span id="line-3718"> scan = new Scan();</span>
<span class="source-line-no">3719</span><span id="line-3719"> scan.addFamily(fam2);</span>
<span class="source-line-no">3720</span><span id="line-3720"> scan.addFamily(fam4);</span>
<span class="source-line-no">3721</span><span id="line-3721"> try (RegionScannerImpl is = region.getScanner(scan)) {</span>
<span class="source-line-no">3722</span><span id="line-3722"> assertEquals(1, is.storeHeap.getHeap().size());</span>
<span class="source-line-no">3723</span><span id="line-3723"> }</span>
<span class="source-line-no">3724</span><span id="line-3724"></span>
<span class="source-line-no">3725</span><span id="line-3725"> scan = new Scan();</span>
<span class="source-line-no">3726</span><span id="line-3726"> try (RegionScannerImpl is = region.getScanner(scan)) {</span>
<span class="source-line-no">3727</span><span id="line-3727"> assertEquals(families.length - 1, is.storeHeap.getHeap().size());</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"></span>
<span class="source-line-no">3731</span><span id="line-3731"> /**</span>
<span class="source-line-no">3732</span><span id="line-3732"> * This method tests https://issues.apache.org/jira/browse/HBASE-2516.</span>
<span class="source-line-no">3733</span><span id="line-3733"> */</span>
<span class="source-line-no">3734</span><span id="line-3734"> @Test</span>
<span class="source-line-no">3735</span><span id="line-3735"> public void testGetScanner_WithRegionClosed() throws IOException {</span>
<span class="source-line-no">3736</span><span id="line-3736"> byte[] fam1 = Bytes.toBytes("fam1");</span>
<span class="source-line-no">3737</span><span id="line-3737"> byte[] fam2 = Bytes.toBytes("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"> byte[][] families = { fam1, fam2 };</span>
<span class="source-line-no">3740</span><span id="line-3740"></span>
<span class="source-line-no">3741</span><span id="line-3741"> // Setting up region</span>
<span class="source-line-no">3742</span><span id="line-3742"> region = initHRegion(tableName, method, CONF, families);</span>
<span class="source-line-no">3743</span><span id="line-3743"> region.closed.set(true);</span>
<span class="source-line-no">3744</span><span id="line-3744"> try {</span>
<span class="source-line-no">3745</span><span id="line-3745"> assertThrows(NotServingRegionException.class, () -&gt; region.getScanner(null));</span>
<span class="source-line-no">3746</span><span id="line-3746"> } finally {</span>
<span class="source-line-no">3747</span><span id="line-3747"> // so we can close the region in tearDown</span>
<span class="source-line-no">3748</span><span id="line-3748"> region.closed.set(false);</span>
<span class="source-line-no">3749</span><span id="line-3749"> }</span>
<span class="source-line-no">3750</span><span id="line-3750"> }</span>
<span class="source-line-no">3751</span><span id="line-3751"></span>
<span class="source-line-no">3752</span><span id="line-3752"> @Test</span>
<span class="source-line-no">3753</span><span id="line-3753"> public void testRegionScanner_Next() throws IOException {</span>
<span class="source-line-no">3754</span><span id="line-3754"> byte[] row1 = Bytes.toBytes("row1");</span>
<span class="source-line-no">3755</span><span id="line-3755"> byte[] row2 = Bytes.toBytes("row2");</span>
<span class="source-line-no">3756</span><span id="line-3756"> byte[] fam1 = Bytes.toBytes("fam1");</span>
<span class="source-line-no">3757</span><span id="line-3757"> byte[] fam2 = Bytes.toBytes("fam2");</span>
<span class="source-line-no">3758</span><span id="line-3758"> byte[] fam3 = Bytes.toBytes("fam3");</span>
<span class="source-line-no">3759</span><span id="line-3759"> byte[] fam4 = Bytes.toBytes("fam4");</span>
<span class="source-line-no">3760</span><span id="line-3760"></span>
<span class="source-line-no">3761</span><span id="line-3761"> byte[][] families = { fam1, fam2, fam3, fam4 };</span>
<span class="source-line-no">3762</span><span id="line-3762"> long ts = EnvironmentEdgeManager.currentTime();</span>
<span class="source-line-no">3763</span><span id="line-3763"></span>
<span class="source-line-no">3764</span><span id="line-3764"> // Setting up region</span>
<span class="source-line-no">3765</span><span id="line-3765"> this.region = initHRegion(tableName, method, CONF, families);</span>
<span class="source-line-no">3766</span><span id="line-3766"> // Putting data in Region</span>
<span class="source-line-no">3767</span><span id="line-3767"> Put put = null;</span>
<span class="source-line-no">3768</span><span id="line-3768"> put = new Put(row1);</span>
<span class="source-line-no">3769</span><span id="line-3769"> put.addColumn(fam1, (byte[]) null, ts, null);</span>
<span class="source-line-no">3770</span><span id="line-3770"> put.addColumn(fam2, (byte[]) null, ts, null);</span>
<span class="source-line-no">3771</span><span id="line-3771"> put.addColumn(fam3, (byte[]) null, ts, null);</span>
<span class="source-line-no">3772</span><span id="line-3772"> put.addColumn(fam4, (byte[]) null, ts, null);</span>
<span class="source-line-no">3773</span><span id="line-3773"> region.put(put);</span>
<span class="source-line-no">3774</span><span id="line-3774"></span>
<span class="source-line-no">3775</span><span id="line-3775"> put = new Put(row2);</span>
<span class="source-line-no">3776</span><span id="line-3776"> put.addColumn(fam1, (byte[]) null, ts, null);</span>
<span class="source-line-no">3777</span><span id="line-3777"> put.addColumn(fam2, (byte[]) null, ts, null);</span>
<span class="source-line-no">3778</span><span id="line-3778"> put.addColumn(fam3, (byte[]) null, ts, null);</span>
<span class="source-line-no">3779</span><span id="line-3779"> put.addColumn(fam4, (byte[]) null, ts, null);</span>
<span class="source-line-no">3780</span><span id="line-3780"> region.put(put);</span>
<span class="source-line-no">3781</span><span id="line-3781"></span>
<span class="source-line-no">3782</span><span id="line-3782"> Scan scan = new Scan();</span>
<span class="source-line-no">3783</span><span id="line-3783"> scan.addFamily(fam2);</span>
<span class="source-line-no">3784</span><span id="line-3784"> scan.addFamily(fam4);</span>
<span class="source-line-no">3785</span><span id="line-3785"> try (InternalScanner is = region.getScanner(scan)) {</span>
<span class="source-line-no">3786</span><span id="line-3786"> List&lt;ExtendedCell&gt; res = null;</span>
<span class="source-line-no">3787</span><span id="line-3787"></span>
<span class="source-line-no">3788</span><span id="line-3788"> // Result 1</span>
<span class="source-line-no">3789</span><span id="line-3789"> List&lt;ExtendedCell&gt; expected1 = new ArrayList&lt;&gt;();</span>
<span class="source-line-no">3790</span><span id="line-3790"> expected1.add(new KeyValue(row1, fam2, null, ts, KeyValue.Type.Put, null));</span>
<span class="source-line-no">3791</span><span id="line-3791"> expected1.add(new KeyValue(row1, fam4, null, ts, KeyValue.Type.Put, null));</span>
<span class="source-line-no">3792</span><span id="line-3792"></span>
<span class="source-line-no">3793</span><span id="line-3793"> res = new ArrayList&lt;&gt;();</span>
<span class="source-line-no">3794</span><span id="line-3794"> is.next(res);</span>
<span class="source-line-no">3795</span><span id="line-3795"> for (int i = 0; i &lt; res.size(); i++) {</span>
<span class="source-line-no">3796</span><span id="line-3796"> assertTrue(PrivateCellUtil.equalsIgnoreMvccVersion(expected1.get(i), res.get(i)));</span>
<span class="source-line-no">3797</span><span id="line-3797"> }</span>
<span class="source-line-no">3798</span><span id="line-3798"></span>
<span class="source-line-no">3799</span><span id="line-3799"> // Result 2</span>
<span class="source-line-no">3800</span><span id="line-3800"> List&lt;ExtendedCell&gt; expected2 = new ArrayList&lt;&gt;();</span>
<span class="source-line-no">3801</span><span id="line-3801"> expected2.add(new KeyValue(row2, fam2, null, ts, KeyValue.Type.Put, null));</span>
<span class="source-line-no">3802</span><span id="line-3802"> expected2.add(new KeyValue(row2, fam4, null, ts, KeyValue.Type.Put, null));</span>
<span class="source-line-no">3803</span><span id="line-3803"></span>
<span class="source-line-no">3804</span><span id="line-3804"> res = new ArrayList&lt;&gt;();</span>
<span class="source-line-no">3805</span><span id="line-3805"> is.next(res);</span>
<span class="source-line-no">3806</span><span id="line-3806"> for (int i = 0; i &lt; res.size(); i++) {</span>
<span class="source-line-no">3807</span><span id="line-3807"> assertTrue(PrivateCellUtil.equalsIgnoreMvccVersion(expected2.get(i), res.get(i)));</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"> }</span>
<span class="source-line-no">3811</span><span id="line-3811"></span>
<span class="source-line-no">3812</span><span id="line-3812"> @Test</span>
<span class="source-line-no">3813</span><span id="line-3813"> public void testScanner_ExplicitColumns_FromMemStore_EnforceVersions() throws IOException {</span>
<span class="source-line-no">3814</span><span id="line-3814"> byte[] row1 = Bytes.toBytes("row1");</span>
<span class="source-line-no">3815</span><span id="line-3815"> byte[] qf1 = Bytes.toBytes("qualifier1");</span>
<span class="source-line-no">3816</span><span id="line-3816"> byte[] qf2 = Bytes.toBytes("qualifier2");</span>
<span class="source-line-no">3817</span><span id="line-3817"> byte[] fam1 = Bytes.toBytes("fam1");</span>
<span class="source-line-no">3818</span><span id="line-3818"> byte[][] families = { fam1 };</span>
<span class="source-line-no">3819</span><span id="line-3819"></span>
<span class="source-line-no">3820</span><span id="line-3820"> long ts1 = EnvironmentEdgeManager.currentTime();</span>
<span class="source-line-no">3821</span><span id="line-3821"> long ts2 = ts1 + 1;</span>
<span class="source-line-no">3822</span><span id="line-3822"> long ts3 = ts1 + 2;</span>
<span class="source-line-no">3823</span><span id="line-3823"></span>
<span class="source-line-no">3824</span><span id="line-3824"> // Setting up region</span>
<span class="source-line-no">3825</span><span id="line-3825"> this.region = initHRegion(tableName, method, CONF, families);</span>
<span class="source-line-no">3826</span><span id="line-3826"> // Putting data in Region</span>
<span class="source-line-no">3827</span><span id="line-3827"> Put put = null;</span>
<span class="source-line-no">3828</span><span id="line-3828"> KeyValue kv13 = new KeyValue(row1, fam1, qf1, ts3, KeyValue.Type.Put, null);</span>
<span class="source-line-no">3829</span><span id="line-3829"> KeyValue kv12 = new KeyValue(row1, fam1, qf1, ts2, KeyValue.Type.Put, null);</span>
<span class="source-line-no">3830</span><span id="line-3830"> KeyValue kv11 = new KeyValue(row1, fam1, qf1, ts1, KeyValue.Type.Put, null);</span>
<span class="source-line-no">3831</span><span id="line-3831"></span>
<span class="source-line-no">3832</span><span id="line-3832"> KeyValue kv23 = new KeyValue(row1, fam1, qf2, ts3, KeyValue.Type.Put, null);</span>
<span class="source-line-no">3833</span><span id="line-3833"> KeyValue kv22 = new KeyValue(row1, fam1, qf2, ts2, KeyValue.Type.Put, null);</span>
<span class="source-line-no">3834</span><span id="line-3834"> KeyValue kv21 = new KeyValue(row1, fam1, qf2, ts1, KeyValue.Type.Put, null);</span>
<span class="source-line-no">3835</span><span id="line-3835"></span>
<span class="source-line-no">3836</span><span id="line-3836"> put = new Put(row1);</span>
<span class="source-line-no">3837</span><span id="line-3837"> put.add(kv13);</span>
<span class="source-line-no">3838</span><span id="line-3838"> put.add(kv12);</span>
<span class="source-line-no">3839</span><span id="line-3839"> put.add(kv11);</span>
<span class="source-line-no">3840</span><span id="line-3840"> put.add(kv23);</span>
<span class="source-line-no">3841</span><span id="line-3841"> put.add(kv22);</span>
<span class="source-line-no">3842</span><span id="line-3842"> put.add(kv21);</span>
<span class="source-line-no">3843</span><span id="line-3843"> region.put(put);</span>
<span class="source-line-no">3844</span><span id="line-3844"></span>
<span class="source-line-no">3845</span><span id="line-3845"> // Expected</span>
<span class="source-line-no">3846</span><span id="line-3846"> List&lt;Cell&gt; expected = new ArrayList&lt;&gt;();</span>
<span class="source-line-no">3847</span><span id="line-3847"> expected.add(kv13);</span>
<span class="source-line-no">3848</span><span id="line-3848"> expected.add(kv12);</span>
<span class="source-line-no">3849</span><span id="line-3849"></span>
<span class="source-line-no">3850</span><span id="line-3850"> Scan scan = new Scan().withStartRow(row1);</span>
<span class="source-line-no">3851</span><span id="line-3851"> scan.addColumn(fam1, qf1);</span>
<span class="source-line-no">3852</span><span id="line-3852"> scan.readVersions(MAX_VERSIONS);</span>
<span class="source-line-no">3853</span><span id="line-3853"> List&lt;Cell&gt; actual = new ArrayList&lt;&gt;();</span>
<span class="source-line-no">3854</span><span id="line-3854"> try (InternalScanner scanner = region.getScanner(scan)) {</span>
<span class="source-line-no">3855</span><span id="line-3855"> boolean hasNext = scanner.next(actual);</span>
<span class="source-line-no">3856</span><span id="line-3856"> assertEquals(false, hasNext);</span>
<span class="source-line-no">3857</span><span id="line-3857"></span>
<span class="source-line-no">3858</span><span id="line-3858"> // Verify result</span>
<span class="source-line-no">3859</span><span id="line-3859"> for (int i = 0; i &lt; expected.size(); i++) {</span>
<span class="source-line-no">3860</span><span id="line-3860"> assertEquals(expected.get(i), actual.get(i));</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"> }</span>
<span class="source-line-no">3864</span><span id="line-3864"></span>
<span class="source-line-no">3865</span><span id="line-3865"> @Test</span>
<span class="source-line-no">3866</span><span id="line-3866"> public void testScanner_ExplicitColumns_FromFilesOnly_EnforceVersions() throws IOException {</span>
<span class="source-line-no">3867</span><span id="line-3867"> byte[] row1 = Bytes.toBytes("row1");</span>
<span class="source-line-no">3868</span><span id="line-3868"> byte[] qf1 = Bytes.toBytes("qualifier1");</span>
<span class="source-line-no">3869</span><span id="line-3869"> byte[] qf2 = Bytes.toBytes("qualifier2");</span>
<span class="source-line-no">3870</span><span id="line-3870"> byte[] fam1 = Bytes.toBytes("fam1");</span>
<span class="source-line-no">3871</span><span id="line-3871"> byte[][] families = { fam1 };</span>
<span class="source-line-no">3872</span><span id="line-3872"></span>
<span class="source-line-no">3873</span><span id="line-3873"> long ts1 = 1;</span>
<span class="source-line-no">3874</span><span id="line-3874"> long ts2 = ts1 + 1;</span>
<span class="source-line-no">3875</span><span id="line-3875"> long ts3 = ts1 + 2;</span>
<span class="source-line-no">3876</span><span id="line-3876"></span>
<span class="source-line-no">3877</span><span id="line-3877"> // Setting up region</span>
<span class="source-line-no">3878</span><span id="line-3878"> this.region = initHRegion(tableName, method, CONF, families);</span>
<span class="source-line-no">3879</span><span id="line-3879"> // Putting data in Region</span>
<span class="source-line-no">3880</span><span id="line-3880"> Put put = null;</span>
<span class="source-line-no">3881</span><span id="line-3881"> KeyValue kv13 = new KeyValue(row1, fam1, qf1, ts3, KeyValue.Type.Put, null);</span>
<span class="source-line-no">3882</span><span id="line-3882"> KeyValue kv12 = new KeyValue(row1, fam1, qf1, ts2, KeyValue.Type.Put, null);</span>
<span class="source-line-no">3883</span><span id="line-3883"> KeyValue kv11 = new KeyValue(row1, fam1, qf1, ts1, KeyValue.Type.Put, null);</span>
<span class="source-line-no">3884</span><span id="line-3884"></span>
<span class="source-line-no">3885</span><span id="line-3885"> KeyValue kv23 = new KeyValue(row1, fam1, qf2, ts3, KeyValue.Type.Put, null);</span>
<span class="source-line-no">3886</span><span id="line-3886"> KeyValue kv22 = new KeyValue(row1, fam1, qf2, ts2, KeyValue.Type.Put, null);</span>
<span class="source-line-no">3887</span><span id="line-3887"> KeyValue kv21 = new KeyValue(row1, fam1, qf2, ts1, KeyValue.Type.Put, null);</span>
<span class="source-line-no">3888</span><span id="line-3888"></span>
<span class="source-line-no">3889</span><span id="line-3889"> put = new Put(row1);</span>
<span class="source-line-no">3890</span><span id="line-3890"> put.add(kv13);</span>
<span class="source-line-no">3891</span><span id="line-3891"> put.add(kv12);</span>
<span class="source-line-no">3892</span><span id="line-3892"> put.add(kv11);</span>
<span class="source-line-no">3893</span><span id="line-3893"> put.add(kv23);</span>
<span class="source-line-no">3894</span><span id="line-3894"> put.add(kv22);</span>
<span class="source-line-no">3895</span><span id="line-3895"> put.add(kv21);</span>
<span class="source-line-no">3896</span><span id="line-3896"> region.put(put);</span>
<span class="source-line-no">3897</span><span id="line-3897"> region.flush(true);</span>
<span class="source-line-no">3898</span><span id="line-3898"></span>
<span class="source-line-no">3899</span><span id="line-3899"> // Expected</span>
<span class="source-line-no">3900</span><span id="line-3900"> List&lt;ExtendedCell&gt; expected = new ArrayList&lt;&gt;();</span>
<span class="source-line-no">3901</span><span id="line-3901"> expected.add(kv13);</span>
<span class="source-line-no">3902</span><span id="line-3902"> expected.add(kv12);</span>
<span class="source-line-no">3903</span><span id="line-3903"> expected.add(kv23);</span>
<span class="source-line-no">3904</span><span id="line-3904"> expected.add(kv22);</span>
<span class="source-line-no">3905</span><span id="line-3905"></span>
<span class="source-line-no">3906</span><span id="line-3906"> Scan scan = new Scan().withStartRow(row1);</span>
<span class="source-line-no">3907</span><span id="line-3907"> scan.addColumn(fam1, qf1);</span>
<span class="source-line-no">3908</span><span id="line-3908"> scan.addColumn(fam1, qf2);</span>
<span class="source-line-no">3909</span><span id="line-3909"> scan.readVersions(MAX_VERSIONS);</span>
<span class="source-line-no">3910</span><span id="line-3910"> List&lt;ExtendedCell&gt; actual = new ArrayList&lt;&gt;();</span>
<span class="source-line-no">3911</span><span id="line-3911"> try (InternalScanner scanner = region.getScanner(scan)) {</span>
<span class="source-line-no">3912</span><span id="line-3912"> boolean hasNext = scanner.next(actual);</span>
<span class="source-line-no">3913</span><span id="line-3913"> assertEquals(false, hasNext);</span>
<span class="source-line-no">3914</span><span id="line-3914"></span>
<span class="source-line-no">3915</span><span id="line-3915"> // Verify result</span>
<span class="source-line-no">3916</span><span id="line-3916"> for (int i = 0; i &lt; expected.size(); i++) {</span>
<span class="source-line-no">3917</span><span id="line-3917"> assertTrue(PrivateCellUtil.equalsIgnoreMvccVersion(expected.get(i), actual.get(i)));</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"> }</span>
<span class="source-line-no">3921</span><span id="line-3921"></span>
<span class="source-line-no">3922</span><span id="line-3922"> @Test</span>
<span class="source-line-no">3923</span><span id="line-3923"> public void testScanner_ExplicitColumns_FromMemStoreAndFiles_EnforceVersions()</span>
<span class="source-line-no">3924</span><span id="line-3924"> throws IOException {</span>
<span class="source-line-no">3925</span><span id="line-3925"> byte[] row1 = Bytes.toBytes("row1");</span>
<span class="source-line-no">3926</span><span id="line-3926"> byte[] fam1 = Bytes.toBytes("fam1");</span>
<span class="source-line-no">3927</span><span id="line-3927"> byte[][] families = { fam1 };</span>
<span class="source-line-no">3928</span><span id="line-3928"> byte[] qf1 = Bytes.toBytes("qualifier1");</span>
<span class="source-line-no">3929</span><span id="line-3929"> byte[] qf2 = Bytes.toBytes("qualifier2");</span>
<span class="source-line-no">3930</span><span id="line-3930"></span>
<span class="source-line-no">3931</span><span id="line-3931"> long ts1 = 1;</span>
<span class="source-line-no">3932</span><span id="line-3932"> long ts2 = ts1 + 1;</span>
<span class="source-line-no">3933</span><span id="line-3933"> long ts3 = ts1 + 2;</span>
<span class="source-line-no">3934</span><span id="line-3934"> long ts4 = ts1 + 3;</span>
<span class="source-line-no">3935</span><span id="line-3935"></span>
<span class="source-line-no">3936</span><span id="line-3936"> // Setting up region</span>
<span class="source-line-no">3937</span><span id="line-3937"> this.region = initHRegion(tableName, method, CONF, families);</span>
<span class="source-line-no">3938</span><span id="line-3938"> // Putting data in Region</span>
<span class="source-line-no">3939</span><span id="line-3939"> KeyValue kv14 = new KeyValue(row1, fam1, qf1, ts4, KeyValue.Type.Put, null);</span>
<span class="source-line-no">3940</span><span id="line-3940"> KeyValue kv13 = new KeyValue(row1, fam1, qf1, ts3, KeyValue.Type.Put, null);</span>
<span class="source-line-no">3941</span><span id="line-3941"> KeyValue kv12 = new KeyValue(row1, fam1, qf1, ts2, KeyValue.Type.Put, null);</span>
<span class="source-line-no">3942</span><span id="line-3942"> KeyValue kv11 = new KeyValue(row1, fam1, qf1, ts1, KeyValue.Type.Put, null);</span>
<span class="source-line-no">3943</span><span id="line-3943"></span>
<span class="source-line-no">3944</span><span id="line-3944"> KeyValue kv24 = new KeyValue(row1, fam1, qf2, ts4, KeyValue.Type.Put, null);</span>
<span class="source-line-no">3945</span><span id="line-3945"> KeyValue kv23 = new KeyValue(row1, fam1, qf2, ts3, KeyValue.Type.Put, null);</span>
<span class="source-line-no">3946</span><span id="line-3946"> KeyValue kv22 = new KeyValue(row1, fam1, qf2, ts2, KeyValue.Type.Put, null);</span>
<span class="source-line-no">3947</span><span id="line-3947"> KeyValue kv21 = new KeyValue(row1, fam1, qf2, ts1, KeyValue.Type.Put, null);</span>
<span class="source-line-no">3948</span><span id="line-3948"></span>
<span class="source-line-no">3949</span><span id="line-3949"> Put put = null;</span>
<span class="source-line-no">3950</span><span id="line-3950"> put = new Put(row1);</span>
<span class="source-line-no">3951</span><span id="line-3951"> put.add(kv14);</span>
<span class="source-line-no">3952</span><span id="line-3952"> put.add(kv24);</span>
<span class="source-line-no">3953</span><span id="line-3953"> region.put(put);</span>
<span class="source-line-no">3954</span><span id="line-3954"> region.flush(true);</span>
<span class="source-line-no">3955</span><span id="line-3955"></span>
<span class="source-line-no">3956</span><span id="line-3956"> put = new Put(row1);</span>
<span class="source-line-no">3957</span><span id="line-3957"> put.add(kv23);</span>
<span class="source-line-no">3958</span><span id="line-3958"> put.add(kv13);</span>
<span class="source-line-no">3959</span><span id="line-3959"> region.put(put);</span>
<span class="source-line-no">3960</span><span id="line-3960"> region.flush(true);</span>
<span class="source-line-no">3961</span><span id="line-3961"></span>
<span class="source-line-no">3962</span><span id="line-3962"> put = new Put(row1);</span>
<span class="source-line-no">3963</span><span id="line-3963"> put.add(kv22);</span>
<span class="source-line-no">3964</span><span id="line-3964"> put.add(kv12);</span>
<span class="source-line-no">3965</span><span id="line-3965"> region.put(put);</span>
<span class="source-line-no">3966</span><span id="line-3966"> region.flush(true);</span>
<span class="source-line-no">3967</span><span id="line-3967"></span>
<span class="source-line-no">3968</span><span id="line-3968"> put = new Put(row1);</span>
<span class="source-line-no">3969</span><span id="line-3969"> put.add(kv21);</span>
<span class="source-line-no">3970</span><span id="line-3970"> put.add(kv11);</span>
<span class="source-line-no">3971</span><span id="line-3971"> region.put(put);</span>
<span class="source-line-no">3972</span><span id="line-3972"></span>
<span class="source-line-no">3973</span><span id="line-3973"> // Expected</span>
<span class="source-line-no">3974</span><span id="line-3974"> List&lt;ExtendedCell&gt; expected = new ArrayList&lt;&gt;();</span>
<span class="source-line-no">3975</span><span id="line-3975"> expected.add(kv14);</span>
<span class="source-line-no">3976</span><span id="line-3976"> expected.add(kv13);</span>
<span class="source-line-no">3977</span><span id="line-3977"> expected.add(kv12);</span>
<span class="source-line-no">3978</span><span id="line-3978"> expected.add(kv24);</span>
<span class="source-line-no">3979</span><span id="line-3979"> expected.add(kv23);</span>
<span class="source-line-no">3980</span><span id="line-3980"> expected.add(kv22);</span>
<span class="source-line-no">3981</span><span id="line-3981"></span>
<span class="source-line-no">3982</span><span id="line-3982"> Scan scan = new Scan().withStartRow(row1);</span>
<span class="source-line-no">3983</span><span id="line-3983"> scan.addColumn(fam1, qf1);</span>
<span class="source-line-no">3984</span><span id="line-3984"> scan.addColumn(fam1, qf2);</span>
<span class="source-line-no">3985</span><span id="line-3985"> int versions = 3;</span>
<span class="source-line-no">3986</span><span id="line-3986"> scan.readVersions(versions);</span>
<span class="source-line-no">3987</span><span id="line-3987"> List&lt;ExtendedCell&gt; actual = new ArrayList&lt;&gt;();</span>
<span class="source-line-no">3988</span><span id="line-3988"> try (InternalScanner scanner = region.getScanner(scan)) {</span>
<span class="source-line-no">3989</span><span id="line-3989"> boolean hasNext = scanner.next(actual);</span>
<span class="source-line-no">3990</span><span id="line-3990"> assertEquals(false, hasNext);</span>
<span class="source-line-no">3991</span><span id="line-3991"></span>
<span class="source-line-no">3992</span><span id="line-3992"> // Verify result</span>
<span class="source-line-no">3993</span><span id="line-3993"> for (int i = 0; i &lt; expected.size(); i++) {</span>
<span class="source-line-no">3994</span><span id="line-3994"> assertTrue(PrivateCellUtil.equalsIgnoreMvccVersion(expected.get(i), actual.get(i)));</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"> }</span>
<span class="source-line-no">3998</span><span id="line-3998"></span>
<span class="source-line-no">3999</span><span id="line-3999"> @Test</span>
<span class="source-line-no">4000</span><span id="line-4000"> public void testScanner_Wildcard_FromMemStore_EnforceVersions() throws IOException {</span>
<span class="source-line-no">4001</span><span id="line-4001"> byte[] row1 = Bytes.toBytes("row1");</span>
<span class="source-line-no">4002</span><span id="line-4002"> byte[] qf1 = Bytes.toBytes("qualifier1");</span>
<span class="source-line-no">4003</span><span id="line-4003"> byte[] qf2 = Bytes.toBytes("qualifier2");</span>
<span class="source-line-no">4004</span><span id="line-4004"> byte[] fam1 = Bytes.toBytes("fam1");</span>
<span class="source-line-no">4005</span><span id="line-4005"> byte[][] families = { fam1 };</span>
<span class="source-line-no">4006</span><span id="line-4006"></span>
<span class="source-line-no">4007</span><span id="line-4007"> long ts1 = EnvironmentEdgeManager.currentTime();</span>
<span class="source-line-no">4008</span><span id="line-4008"> long ts2 = ts1 + 1;</span>
<span class="source-line-no">4009</span><span id="line-4009"> long ts3 = ts1 + 2;</span>
<span class="source-line-no">4010</span><span id="line-4010"></span>
<span class="source-line-no">4011</span><span id="line-4011"> // Setting up region</span>
<span class="source-line-no">4012</span><span id="line-4012"> this.region = initHRegion(tableName, method, CONF, families);</span>
<span class="source-line-no">4013</span><span id="line-4013"> // Putting data in Region</span>
<span class="source-line-no">4014</span><span id="line-4014"> Put put = null;</span>
<span class="source-line-no">4015</span><span id="line-4015"> KeyValue kv13 = new KeyValue(row1, fam1, qf1, ts3, KeyValue.Type.Put, null);</span>
<span class="source-line-no">4016</span><span id="line-4016"> KeyValue kv12 = new KeyValue(row1, fam1, qf1, ts2, KeyValue.Type.Put, null);</span>
<span class="source-line-no">4017</span><span id="line-4017"> KeyValue kv11 = new KeyValue(row1, fam1, qf1, ts1, KeyValue.Type.Put, null);</span>
<span class="source-line-no">4018</span><span id="line-4018"></span>
<span class="source-line-no">4019</span><span id="line-4019"> KeyValue kv23 = new KeyValue(row1, fam1, qf2, ts3, KeyValue.Type.Put, null);</span>
<span class="source-line-no">4020</span><span id="line-4020"> KeyValue kv22 = new KeyValue(row1, fam1, qf2, ts2, KeyValue.Type.Put, null);</span>
<span class="source-line-no">4021</span><span id="line-4021"> KeyValue kv21 = new KeyValue(row1, fam1, qf2, ts1, KeyValue.Type.Put, null);</span>
<span class="source-line-no">4022</span><span id="line-4022"></span>
<span class="source-line-no">4023</span><span id="line-4023"> put = new Put(row1);</span>
<span class="source-line-no">4024</span><span id="line-4024"> put.add(kv13);</span>
<span class="source-line-no">4025</span><span id="line-4025"> put.add(kv12);</span>
<span class="source-line-no">4026</span><span id="line-4026"> put.add(kv11);</span>
<span class="source-line-no">4027</span><span id="line-4027"> put.add(kv23);</span>
<span class="source-line-no">4028</span><span id="line-4028"> put.add(kv22);</span>
<span class="source-line-no">4029</span><span id="line-4029"> put.add(kv21);</span>
<span class="source-line-no">4030</span><span id="line-4030"> region.put(put);</span>
<span class="source-line-no">4031</span><span id="line-4031"></span>
<span class="source-line-no">4032</span><span id="line-4032"> // Expected</span>
<span class="source-line-no">4033</span><span id="line-4033"> List&lt;Cell&gt; expected = new ArrayList&lt;&gt;();</span>
<span class="source-line-no">4034</span><span id="line-4034"> expected.add(kv13);</span>
<span class="source-line-no">4035</span><span id="line-4035"> expected.add(kv12);</span>
<span class="source-line-no">4036</span><span id="line-4036"> expected.add(kv23);</span>
<span class="source-line-no">4037</span><span id="line-4037"> expected.add(kv22);</span>
<span class="source-line-no">4038</span><span id="line-4038"></span>
<span class="source-line-no">4039</span><span id="line-4039"> Scan scan = new Scan().withStartRow(row1);</span>
<span class="source-line-no">4040</span><span id="line-4040"> scan.addFamily(fam1);</span>
<span class="source-line-no">4041</span><span id="line-4041"> scan.readVersions(MAX_VERSIONS);</span>
<span class="source-line-no">4042</span><span id="line-4042"> List&lt;Cell&gt; actual = new ArrayList&lt;&gt;();</span>
<span class="source-line-no">4043</span><span id="line-4043"> try (InternalScanner scanner = region.getScanner(scan)) {</span>
<span class="source-line-no">4044</span><span id="line-4044"> boolean hasNext = scanner.next(actual);</span>
<span class="source-line-no">4045</span><span id="line-4045"> assertEquals(false, hasNext);</span>
<span class="source-line-no">4046</span><span id="line-4046"></span>
<span class="source-line-no">4047</span><span id="line-4047"> // Verify result</span>
<span class="source-line-no">4048</span><span id="line-4048"> for (int i = 0; i &lt; expected.size(); i++) {</span>
<span class="source-line-no">4049</span><span id="line-4049"> assertEquals(expected.get(i), actual.get(i));</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"> }</span>
<span class="source-line-no">4053</span><span id="line-4053"></span>
<span class="source-line-no">4054</span><span id="line-4054"> @Test</span>
<span class="source-line-no">4055</span><span id="line-4055"> public void testScanner_Wildcard_FromFilesOnly_EnforceVersions() throws IOException {</span>
<span class="source-line-no">4056</span><span id="line-4056"> byte[] row1 = Bytes.toBytes("row1");</span>
<span class="source-line-no">4057</span><span id="line-4057"> byte[] qf1 = Bytes.toBytes("qualifier1");</span>
<span class="source-line-no">4058</span><span id="line-4058"> byte[] qf2 = Bytes.toBytes("qualifier2");</span>
<span class="source-line-no">4059</span><span id="line-4059"> byte[] fam1 = Bytes.toBytes("fam1");</span>
<span class="source-line-no">4060</span><span id="line-4060"></span>
<span class="source-line-no">4061</span><span id="line-4061"> long ts1 = 1;</span>
<span class="source-line-no">4062</span><span id="line-4062"> long ts2 = ts1 + 1;</span>
<span class="source-line-no">4063</span><span id="line-4063"> long ts3 = ts1 + 2;</span>
<span class="source-line-no">4064</span><span id="line-4064"></span>
<span class="source-line-no">4065</span><span id="line-4065"> // Setting up region</span>
<span class="source-line-no">4066</span><span id="line-4066"> this.region = initHRegion(tableName, method, CONF, fam1);</span>
<span class="source-line-no">4067</span><span id="line-4067"> // Putting data in Region</span>
<span class="source-line-no">4068</span><span id="line-4068"> Put put = null;</span>
<span class="source-line-no">4069</span><span id="line-4069"> KeyValue kv13 = new KeyValue(row1, fam1, qf1, ts3, KeyValue.Type.Put, null);</span>
<span class="source-line-no">4070</span><span id="line-4070"> KeyValue kv12 = new KeyValue(row1, fam1, qf1, ts2, KeyValue.Type.Put, null);</span>
<span class="source-line-no">4071</span><span id="line-4071"> KeyValue kv11 = new KeyValue(row1, fam1, qf1, ts1, KeyValue.Type.Put, null);</span>
<span class="source-line-no">4072</span><span id="line-4072"></span>
<span class="source-line-no">4073</span><span id="line-4073"> KeyValue kv23 = new KeyValue(row1, fam1, qf2, ts3, KeyValue.Type.Put, null);</span>
<span class="source-line-no">4074</span><span id="line-4074"> KeyValue kv22 = new KeyValue(row1, fam1, qf2, ts2, KeyValue.Type.Put, null);</span>
<span class="source-line-no">4075</span><span id="line-4075"> KeyValue kv21 = new KeyValue(row1, fam1, qf2, ts1, KeyValue.Type.Put, null);</span>
<span class="source-line-no">4076</span><span id="line-4076"></span>
<span class="source-line-no">4077</span><span id="line-4077"> put = new Put(row1);</span>
<span class="source-line-no">4078</span><span id="line-4078"> put.add(kv13);</span>
<span class="source-line-no">4079</span><span id="line-4079"> put.add(kv12);</span>
<span class="source-line-no">4080</span><span id="line-4080"> put.add(kv11);</span>
<span class="source-line-no">4081</span><span id="line-4081"> put.add(kv23);</span>
<span class="source-line-no">4082</span><span id="line-4082"> put.add(kv22);</span>
<span class="source-line-no">4083</span><span id="line-4083"> put.add(kv21);</span>
<span class="source-line-no">4084</span><span id="line-4084"> region.put(put);</span>
<span class="source-line-no">4085</span><span id="line-4085"> region.flush(true);</span>
<span class="source-line-no">4086</span><span id="line-4086"></span>
<span class="source-line-no">4087</span><span id="line-4087"> // Expected</span>
<span class="source-line-no">4088</span><span id="line-4088"> List&lt;ExtendedCell&gt; expected = new ArrayList&lt;&gt;();</span>
<span class="source-line-no">4089</span><span id="line-4089"> expected.add(kv13);</span>
<span class="source-line-no">4090</span><span id="line-4090"> expected.add(kv12);</span>
<span class="source-line-no">4091</span><span id="line-4091"> expected.add(kv23);</span>
<span class="source-line-no">4092</span><span id="line-4092"> expected.add(kv22);</span>
<span class="source-line-no">4093</span><span id="line-4093"></span>
<span class="source-line-no">4094</span><span id="line-4094"> Scan scan = new Scan().withStartRow(row1);</span>
<span class="source-line-no">4095</span><span id="line-4095"> scan.addFamily(fam1);</span>
<span class="source-line-no">4096</span><span id="line-4096"> scan.readVersions(MAX_VERSIONS);</span>
<span class="source-line-no">4097</span><span id="line-4097"> List&lt;ExtendedCell&gt; actual = new ArrayList&lt;&gt;();</span>
<span class="source-line-no">4098</span><span id="line-4098"> try (InternalScanner scanner = region.getScanner(scan)) {</span>
<span class="source-line-no">4099</span><span id="line-4099"> boolean hasNext = scanner.next(actual);</span>
<span class="source-line-no">4100</span><span id="line-4100"> assertEquals(false, hasNext);</span>
<span class="source-line-no">4101</span><span id="line-4101"></span>
<span class="source-line-no">4102</span><span id="line-4102"> // Verify result</span>
<span class="source-line-no">4103</span><span id="line-4103"> for (int i = 0; i &lt; expected.size(); i++) {</span>
<span class="source-line-no">4104</span><span id="line-4104"> assertTrue(PrivateCellUtil.equalsIgnoreMvccVersion(expected.get(i), actual.get(i)));</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"> }</span>
<span class="source-line-no">4108</span><span id="line-4108"></span>
<span class="source-line-no">4109</span><span id="line-4109"> @Test</span>
<span class="source-line-no">4110</span><span id="line-4110"> public void testScanner_StopRow1542() throws IOException {</span>
<span class="source-line-no">4111</span><span id="line-4111"> byte[] family = Bytes.toBytes("testFamily");</span>
<span class="source-line-no">4112</span><span id="line-4112"> this.region = initHRegion(tableName, method, CONF, family);</span>
<span class="source-line-no">4113</span><span id="line-4113"> byte[] row1 = Bytes.toBytes("row111");</span>
<span class="source-line-no">4114</span><span id="line-4114"> byte[] row2 = Bytes.toBytes("row222");</span>
<span class="source-line-no">4115</span><span id="line-4115"> byte[] row3 = Bytes.toBytes("row333");</span>
<span class="source-line-no">4116</span><span id="line-4116"> byte[] row4 = Bytes.toBytes("row444");</span>
<span class="source-line-no">4117</span><span id="line-4117"> byte[] row5 = Bytes.toBytes("row555");</span>
<span class="source-line-no">4118</span><span id="line-4118"></span>
<span class="source-line-no">4119</span><span id="line-4119"> byte[] col1 = Bytes.toBytes("Pub111");</span>
<span class="source-line-no">4120</span><span id="line-4120"> byte[] col2 = Bytes.toBytes("Pub222");</span>
<span class="source-line-no">4121</span><span id="line-4121"></span>
<span class="source-line-no">4122</span><span id="line-4122"> Put put = new Put(row1);</span>
<span class="source-line-no">4123</span><span id="line-4123"> put.addColumn(family, col1, Bytes.toBytes(10L));</span>
<span class="source-line-no">4124</span><span id="line-4124"> region.put(put);</span>
<span class="source-line-no">4125</span><span id="line-4125"></span>
<span class="source-line-no">4126</span><span id="line-4126"> put = new Put(row2);</span>
<span class="source-line-no">4127</span><span id="line-4127"> put.addColumn(family, col1, Bytes.toBytes(15L));</span>
<span class="source-line-no">4128</span><span id="line-4128"> region.put(put);</span>
<span class="source-line-no">4129</span><span id="line-4129"></span>
<span class="source-line-no">4130</span><span id="line-4130"> put = new Put(row3);</span>
<span class="source-line-no">4131</span><span id="line-4131"> put.addColumn(family, col2, Bytes.toBytes(20L));</span>
<span class="source-line-no">4132</span><span id="line-4132"> region.put(put);</span>
<span class="source-line-no">4133</span><span id="line-4133"></span>
<span class="source-line-no">4134</span><span id="line-4134"> put = new Put(row4);</span>
<span class="source-line-no">4135</span><span id="line-4135"> put.addColumn(family, col2, Bytes.toBytes(30L));</span>
<span class="source-line-no">4136</span><span id="line-4136"> region.put(put);</span>
<span class="source-line-no">4137</span><span id="line-4137"></span>
<span class="source-line-no">4138</span><span id="line-4138"> put = new Put(row5);</span>
<span class="source-line-no">4139</span><span id="line-4139"> put.addColumn(family, col1, Bytes.toBytes(40L));</span>
<span class="source-line-no">4140</span><span id="line-4140"> region.put(put);</span>
<span class="source-line-no">4141</span><span id="line-4141"></span>
<span class="source-line-no">4142</span><span id="line-4142"> Scan scan = new Scan().withStartRow(row3).withStopRow(row4);</span>
<span class="source-line-no">4143</span><span id="line-4143"> scan.readAllVersions();</span>
<span class="source-line-no">4144</span><span id="line-4144"> scan.addColumn(family, col1);</span>
<span class="source-line-no">4145</span><span id="line-4145"> try (InternalScanner s = region.getScanner(scan)) {</span>
<span class="source-line-no">4146</span><span id="line-4146"> List&lt;Cell&gt; results = new ArrayList&lt;&gt;();</span>
<span class="source-line-no">4147</span><span id="line-4147"> assertEquals(false, s.next(results));</span>
<span class="source-line-no">4148</span><span id="line-4148"> assertEquals(0, results.size());</span>
<span class="source-line-no">4149</span><span id="line-4149"> }</span>
<span class="source-line-no">4150</span><span id="line-4150"> }</span>
<span class="source-line-no">4151</span><span id="line-4151"></span>
<span class="source-line-no">4152</span><span id="line-4152"> @Test</span>
<span class="source-line-no">4153</span><span id="line-4153"> public void testScanner_Wildcard_FromMemStoreAndFiles_EnforceVersions() throws IOException {</span>
<span class="source-line-no">4154</span><span id="line-4154"> byte[] row1 = Bytes.toBytes("row1");</span>
<span class="source-line-no">4155</span><span id="line-4155"> byte[] fam1 = Bytes.toBytes("fam1");</span>
<span class="source-line-no">4156</span><span id="line-4156"> byte[] qf1 = Bytes.toBytes("qualifier1");</span>
<span class="source-line-no">4157</span><span id="line-4157"> byte[] qf2 = Bytes.toBytes("quateslifier2");</span>
<span class="source-line-no">4158</span><span id="line-4158"></span>
<span class="source-line-no">4159</span><span id="line-4159"> long ts1 = 1;</span>
<span class="source-line-no">4160</span><span id="line-4160"> long ts2 = ts1 + 1;</span>
<span class="source-line-no">4161</span><span id="line-4161"> long ts3 = ts1 + 2;</span>
<span class="source-line-no">4162</span><span id="line-4162"> long ts4 = ts1 + 3;</span>
<span class="source-line-no">4163</span><span id="line-4163"></span>
<span class="source-line-no">4164</span><span id="line-4164"> // Setting up region</span>
<span class="source-line-no">4165</span><span id="line-4165"> this.region = initHRegion(tableName, method, CONF, fam1);</span>
<span class="source-line-no">4166</span><span id="line-4166"> // Putting data in Region</span>
<span class="source-line-no">4167</span><span id="line-4167"> KeyValue kv14 = new KeyValue(row1, fam1, qf1, ts4, KeyValue.Type.Put, null);</span>
<span class="source-line-no">4168</span><span id="line-4168"> KeyValue kv13 = new KeyValue(row1, fam1, qf1, ts3, KeyValue.Type.Put, null);</span>
<span class="source-line-no">4169</span><span id="line-4169"> KeyValue kv12 = new KeyValue(row1, fam1, qf1, ts2, KeyValue.Type.Put, null);</span>
<span class="source-line-no">4170</span><span id="line-4170"> KeyValue kv11 = new KeyValue(row1, fam1, qf1, ts1, KeyValue.Type.Put, null);</span>
<span class="source-line-no">4171</span><span id="line-4171"></span>
<span class="source-line-no">4172</span><span id="line-4172"> KeyValue kv24 = new KeyValue(row1, fam1, qf2, ts4, KeyValue.Type.Put, null);</span>
<span class="source-line-no">4173</span><span id="line-4173"> KeyValue kv23 = new KeyValue(row1, fam1, qf2, ts3, KeyValue.Type.Put, null);</span>
<span class="source-line-no">4174</span><span id="line-4174"> KeyValue kv22 = new KeyValue(row1, fam1, qf2, ts2, KeyValue.Type.Put, null);</span>
<span class="source-line-no">4175</span><span id="line-4175"> KeyValue kv21 = new KeyValue(row1, fam1, qf2, ts1, KeyValue.Type.Put, null);</span>
<span class="source-line-no">4176</span><span id="line-4176"></span>
<span class="source-line-no">4177</span><span id="line-4177"> Put put = null;</span>
<span class="source-line-no">4178</span><span id="line-4178"> put = new Put(row1);</span>
<span class="source-line-no">4179</span><span id="line-4179"> put.add(kv14);</span>
<span class="source-line-no">4180</span><span id="line-4180"> put.add(kv24);</span>
<span class="source-line-no">4181</span><span id="line-4181"> region.put(put);</span>
<span class="source-line-no">4182</span><span id="line-4182"> region.flush(true);</span>
<span class="source-line-no">4183</span><span id="line-4183"></span>
<span class="source-line-no">4184</span><span id="line-4184"> put = new Put(row1);</span>
<span class="source-line-no">4185</span><span id="line-4185"> put.add(kv23);</span>
<span class="source-line-no">4186</span><span id="line-4186"> put.add(kv13);</span>
<span class="source-line-no">4187</span><span id="line-4187"> region.put(put);</span>
<span class="source-line-no">4188</span><span id="line-4188"> region.flush(true);</span>
<span class="source-line-no">4189</span><span id="line-4189"></span>
<span class="source-line-no">4190</span><span id="line-4190"> put = new Put(row1);</span>
<span class="source-line-no">4191</span><span id="line-4191"> put.add(kv22);</span>
<span class="source-line-no">4192</span><span id="line-4192"> put.add(kv12);</span>
<span class="source-line-no">4193</span><span id="line-4193"> region.put(put);</span>
<span class="source-line-no">4194</span><span id="line-4194"> region.flush(true);</span>
<span class="source-line-no">4195</span><span id="line-4195"></span>
<span class="source-line-no">4196</span><span id="line-4196"> put = new Put(row1);</span>
<span class="source-line-no">4197</span><span id="line-4197"> put.add(kv21);</span>
<span class="source-line-no">4198</span><span id="line-4198"> put.add(kv11);</span>
<span class="source-line-no">4199</span><span id="line-4199"> region.put(put);</span>
<span class="source-line-no">4200</span><span id="line-4200"></span>
<span class="source-line-no">4201</span><span id="line-4201"> // Expected</span>
<span class="source-line-no">4202</span><span id="line-4202"> List&lt;KeyValue&gt; expected = new ArrayList&lt;&gt;();</span>
<span class="source-line-no">4203</span><span id="line-4203"> expected.add(kv14);</span>
<span class="source-line-no">4204</span><span id="line-4204"> expected.add(kv13);</span>
<span class="source-line-no">4205</span><span id="line-4205"> expected.add(kv12);</span>
<span class="source-line-no">4206</span><span id="line-4206"> expected.add(kv24);</span>
<span class="source-line-no">4207</span><span id="line-4207"> expected.add(kv23);</span>
<span class="source-line-no">4208</span><span id="line-4208"> expected.add(kv22);</span>
<span class="source-line-no">4209</span><span id="line-4209"></span>
<span class="source-line-no">4210</span><span id="line-4210"> Scan scan = new Scan().withStartRow(row1);</span>
<span class="source-line-no">4211</span><span id="line-4211"> int versions = 3;</span>
<span class="source-line-no">4212</span><span id="line-4212"> scan.readVersions(versions);</span>
<span class="source-line-no">4213</span><span id="line-4213"> List&lt;ExtendedCell&gt; actual = new ArrayList&lt;&gt;();</span>
<span class="source-line-no">4214</span><span id="line-4214"> try (InternalScanner scanner = region.getScanner(scan)) {</span>
<span class="source-line-no">4215</span><span id="line-4215"> boolean hasNext = scanner.next(actual);</span>
<span class="source-line-no">4216</span><span id="line-4216"> assertEquals(false, hasNext);</span>
<span class="source-line-no">4217</span><span id="line-4217"></span>
<span class="source-line-no">4218</span><span id="line-4218"> // Verify result</span>
<span class="source-line-no">4219</span><span id="line-4219"> for (int i = 0; i &lt; expected.size(); i++) {</span>
<span class="source-line-no">4220</span><span id="line-4220"> assertTrue(PrivateCellUtil.equalsIgnoreMvccVersion(expected.get(i), actual.get(i)));</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"></span>
<span class="source-line-no">4225</span><span id="line-4225"> /**</span>
<span class="source-line-no">4226</span><span id="line-4226"> * Added for HBASE-5416 Here we test scan optimization when only subset of CFs are used in filter</span>
<span class="source-line-no">4227</span><span id="line-4227"> * conditions.</span>
<span class="source-line-no">4228</span><span id="line-4228"> */</span>
<span class="source-line-no">4229</span><span id="line-4229"> @Test</span>
<span class="source-line-no">4230</span><span id="line-4230"> public void testScanner_JoinedScanners() throws IOException {</span>
<span class="source-line-no">4231</span><span id="line-4231"> byte[] cf_essential = Bytes.toBytes("essential");</span>
<span class="source-line-no">4232</span><span id="line-4232"> byte[] cf_joined = Bytes.toBytes("joined");</span>
<span class="source-line-no">4233</span><span id="line-4233"> byte[] cf_alpha = Bytes.toBytes("alpha");</span>
<span class="source-line-no">4234</span><span id="line-4234"> this.region = initHRegion(tableName, method, CONF, cf_essential, cf_joined, cf_alpha);</span>
<span class="source-line-no">4235</span><span id="line-4235"> byte[] row1 = Bytes.toBytes("row1");</span>
<span class="source-line-no">4236</span><span id="line-4236"> byte[] row2 = Bytes.toBytes("row2");</span>
<span class="source-line-no">4237</span><span id="line-4237"> byte[] row3 = Bytes.toBytes("row3");</span>
<span class="source-line-no">4238</span><span id="line-4238"></span>
<span class="source-line-no">4239</span><span id="line-4239"> byte[] col_normal = Bytes.toBytes("d");</span>
<span class="source-line-no">4240</span><span id="line-4240"> byte[] col_alpha = Bytes.toBytes("a");</span>
<span class="source-line-no">4241</span><span id="line-4241"></span>
<span class="source-line-no">4242</span><span id="line-4242"> byte[] filtered_val = Bytes.toBytes(3);</span>
<span class="source-line-no">4243</span><span id="line-4243"></span>
<span class="source-line-no">4244</span><span id="line-4244"> Put put = new Put(row1);</span>
<span class="source-line-no">4245</span><span id="line-4245"> put.addColumn(cf_essential, col_normal, Bytes.toBytes(1));</span>
<span class="source-line-no">4246</span><span id="line-4246"> put.addColumn(cf_joined, col_alpha, Bytes.toBytes(1));</span>
<span class="source-line-no">4247</span><span id="line-4247"> region.put(put);</span>
<span class="source-line-no">4248</span><span id="line-4248"></span>
<span class="source-line-no">4249</span><span id="line-4249"> put = new Put(row2);</span>
<span class="source-line-no">4250</span><span id="line-4250"> put.addColumn(cf_essential, col_alpha, Bytes.toBytes(2));</span>
<span class="source-line-no">4251</span><span id="line-4251"> put.addColumn(cf_joined, col_normal, Bytes.toBytes(2));</span>
<span class="source-line-no">4252</span><span id="line-4252"> put.addColumn(cf_alpha, col_alpha, Bytes.toBytes(2));</span>
<span class="source-line-no">4253</span><span id="line-4253"> region.put(put);</span>
<span class="source-line-no">4254</span><span id="line-4254"></span>
<span class="source-line-no">4255</span><span id="line-4255"> put = new Put(row3);</span>
<span class="source-line-no">4256</span><span id="line-4256"> put.addColumn(cf_essential, col_normal, filtered_val);</span>
<span class="source-line-no">4257</span><span id="line-4257"> put.addColumn(cf_joined, col_normal, filtered_val);</span>
<span class="source-line-no">4258</span><span id="line-4258"> region.put(put);</span>
<span class="source-line-no">4259</span><span id="line-4259"></span>
<span class="source-line-no">4260</span><span id="line-4260"> // Check two things:</span>
<span class="source-line-no">4261</span><span id="line-4261"> // 1. result list contains expected values</span>
<span class="source-line-no">4262</span><span id="line-4262"> // 2. result list is sorted properly</span>
<span class="source-line-no">4263</span><span id="line-4263"></span>
<span class="source-line-no">4264</span><span id="line-4264"> Scan scan = new Scan();</span>
<span class="source-line-no">4265</span><span id="line-4265"> Filter filter = new SingleColumnValueExcludeFilter(cf_essential, col_normal,</span>
<span class="source-line-no">4266</span><span id="line-4266"> CompareOperator.NOT_EQUAL, filtered_val);</span>
<span class="source-line-no">4267</span><span id="line-4267"> scan.setFilter(filter);</span>
<span class="source-line-no">4268</span><span id="line-4268"> scan.setLoadColumnFamiliesOnDemand(true);</span>
<span class="source-line-no">4269</span><span id="line-4269"> try (InternalScanner s = region.getScanner(scan)) {</span>
<span class="source-line-no">4270</span><span id="line-4270"> List&lt;Cell&gt; results = new ArrayList&lt;&gt;();</span>
<span class="source-line-no">4271</span><span id="line-4271"> assertTrue(s.next(results));</span>
<span class="source-line-no">4272</span><span id="line-4272"> assertEquals(1, results.size());</span>
<span class="source-line-no">4273</span><span id="line-4273"> results.clear();</span>
<span class="source-line-no">4274</span><span id="line-4274"></span>
<span class="source-line-no">4275</span><span id="line-4275"> assertTrue(s.next(results));</span>
<span class="source-line-no">4276</span><span id="line-4276"> assertEquals(3, results.size());</span>
<span class="source-line-no">4277</span><span id="line-4277"> assertTrue("orderCheck", CellUtil.matchingFamily(results.get(0), cf_alpha));</span>
<span class="source-line-no">4278</span><span id="line-4278"> assertTrue("orderCheck", CellUtil.matchingFamily(results.get(1), cf_essential));</span>
<span class="source-line-no">4279</span><span id="line-4279"> assertTrue("orderCheck", CellUtil.matchingFamily(results.get(2), cf_joined));</span>
<span class="source-line-no">4280</span><span id="line-4280"> results.clear();</span>
<span class="source-line-no">4281</span><span id="line-4281"></span>
<span class="source-line-no">4282</span><span id="line-4282"> assertFalse(s.next(results));</span>
<span class="source-line-no">4283</span><span id="line-4283"> assertEquals(0, results.size());</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"></span>
<span class="source-line-no">4287</span><span id="line-4287"> /**</span>
<span class="source-line-no">4288</span><span id="line-4288"> * HBASE-5416 Test case when scan limits amount of KVs returned on each next() call.</span>
<span class="source-line-no">4289</span><span id="line-4289"> */</span>
<span class="source-line-no">4290</span><span id="line-4290"> @Test</span>
<span class="source-line-no">4291</span><span id="line-4291"> public void testScanner_JoinedScannersWithLimits() throws IOException {</span>
<span class="source-line-no">4292</span><span id="line-4292"> final byte[] cf_first = Bytes.toBytes("first");</span>
<span class="source-line-no">4293</span><span id="line-4293"> final byte[] cf_second = Bytes.toBytes("second");</span>
<span class="source-line-no">4294</span><span id="line-4294"></span>
<span class="source-line-no">4295</span><span id="line-4295"> this.region = initHRegion(tableName, method, CONF, cf_first, cf_second);</span>
<span class="source-line-no">4296</span><span id="line-4296"> final byte[] col_a = Bytes.toBytes("a");</span>
<span class="source-line-no">4297</span><span id="line-4297"> final byte[] col_b = Bytes.toBytes("b");</span>
<span class="source-line-no">4298</span><span id="line-4298"></span>
<span class="source-line-no">4299</span><span id="line-4299"> Put put;</span>
<span class="source-line-no">4300</span><span id="line-4300"></span>
<span class="source-line-no">4301</span><span id="line-4301"> for (int i = 0; i &lt; 10; i++) {</span>
<span class="source-line-no">4302</span><span id="line-4302"> put = new Put(Bytes.toBytes("r" + Integer.toString(i)));</span>
<span class="source-line-no">4303</span><span id="line-4303"> put.addColumn(cf_first, col_a, Bytes.toBytes(i));</span>
<span class="source-line-no">4304</span><span id="line-4304"> if (i &lt; 5) {</span>
<span class="source-line-no">4305</span><span id="line-4305"> put.addColumn(cf_first, col_b, Bytes.toBytes(i));</span>
<span class="source-line-no">4306</span><span id="line-4306"> put.addColumn(cf_second, col_a, Bytes.toBytes(i));</span>
<span class="source-line-no">4307</span><span id="line-4307"> put.addColumn(cf_second, col_b, Bytes.toBytes(i));</span>
<span class="source-line-no">4308</span><span id="line-4308"> }</span>
<span class="source-line-no">4309</span><span id="line-4309"> region.put(put);</span>
<span class="source-line-no">4310</span><span id="line-4310"> }</span>
<span class="source-line-no">4311</span><span id="line-4311"></span>
<span class="source-line-no">4312</span><span id="line-4312"> Scan scan = new Scan();</span>
<span class="source-line-no">4313</span><span id="line-4313"> scan.setLoadColumnFamiliesOnDemand(true);</span>
<span class="source-line-no">4314</span><span id="line-4314"> Filter bogusFilter = new FilterBase() {</span>
<span class="source-line-no">4315</span><span id="line-4315"> @Override</span>
<span class="source-line-no">4316</span><span id="line-4316"> public ReturnCode filterCell(final Cell ignored) throws IOException {</span>
<span class="source-line-no">4317</span><span id="line-4317"> return ReturnCode.INCLUDE;</span>
<span class="source-line-no">4318</span><span id="line-4318"> }</span>
<span class="source-line-no">4319</span><span id="line-4319"></span>
<span class="source-line-no">4320</span><span id="line-4320"> @Override</span>
<span class="source-line-no">4321</span><span id="line-4321"> public boolean isFamilyEssential(byte[] name) {</span>
<span class="source-line-no">4322</span><span id="line-4322"> return Bytes.equals(name, cf_first);</span>
<span class="source-line-no">4323</span><span id="line-4323"> }</span>
<span class="source-line-no">4324</span><span id="line-4324"> };</span>
<span class="source-line-no">4325</span><span id="line-4325"></span>
<span class="source-line-no">4326</span><span id="line-4326"> scan.setFilter(bogusFilter);</span>
<span class="source-line-no">4327</span><span id="line-4327"> try (InternalScanner s = region.getScanner(scan)) {</span>
<span class="source-line-no">4328</span><span id="line-4328"> // Our data looks like this:</span>
<span class="source-line-no">4329</span><span id="line-4329"> // r0: first:a, first:b, second:a, second:b</span>
<span class="source-line-no">4330</span><span id="line-4330"> // r1: first:a, first:b, second:a, second:b</span>
<span class="source-line-no">4331</span><span id="line-4331"> // r2: first:a, first:b, second:a, second:b</span>
<span class="source-line-no">4332</span><span id="line-4332"> // r3: first:a, first:b, second:a, second:b</span>
<span class="source-line-no">4333</span><span id="line-4333"> // r4: first:a, first:b, second:a, second:b</span>
<span class="source-line-no">4334</span><span id="line-4334"> // r5: first:a</span>
<span class="source-line-no">4335</span><span id="line-4335"> // r6: first:a</span>
<span class="source-line-no">4336</span><span id="line-4336"> // r7: first:a</span>
<span class="source-line-no">4337</span><span id="line-4337"> // r8: first:a</span>
<span class="source-line-no">4338</span><span id="line-4338"> // r9: first:a</span>
<span class="source-line-no">4339</span><span id="line-4339"></span>
<span class="source-line-no">4340</span><span id="line-4340"> // But due to next's limit set to 3, we should get this:</span>
<span class="source-line-no">4341</span><span id="line-4341"> // r0: first:a, first:b, second:a</span>
<span class="source-line-no">4342</span><span id="line-4342"> // r0: second:b</span>
<span class="source-line-no">4343</span><span id="line-4343"> // r1: first:a, first:b, second:a</span>
<span class="source-line-no">4344</span><span id="line-4344"> // r1: second:b</span>
<span class="source-line-no">4345</span><span id="line-4345"> // r2: first:a, first:b, second:a</span>
<span class="source-line-no">4346</span><span id="line-4346"> // r2: second:b</span>
<span class="source-line-no">4347</span><span id="line-4347"> // r3: first:a, first:b, second:a</span>
<span class="source-line-no">4348</span><span id="line-4348"> // r3: second:b</span>
<span class="source-line-no">4349</span><span id="line-4349"> // r4: first:a, first:b, second:a</span>
<span class="source-line-no">4350</span><span id="line-4350"> // r4: second:b</span>
<span class="source-line-no">4351</span><span id="line-4351"> // r5: first:a</span>
<span class="source-line-no">4352</span><span id="line-4352"> // r6: first:a</span>
<span class="source-line-no">4353</span><span id="line-4353"> // r7: first:a</span>
<span class="source-line-no">4354</span><span id="line-4354"> // r8: first:a</span>
<span class="source-line-no">4355</span><span id="line-4355"> // r9: first:a</span>
<span class="source-line-no">4356</span><span id="line-4356"></span>
<span class="source-line-no">4357</span><span id="line-4357"> List&lt;Cell&gt; results = new ArrayList&lt;&gt;();</span>
<span class="source-line-no">4358</span><span id="line-4358"> int index = 0;</span>
<span class="source-line-no">4359</span><span id="line-4359"> ScannerContext scannerContext = ScannerContext.newBuilder().setBatchLimit(3).build();</span>
<span class="source-line-no">4360</span><span id="line-4360"> while (true) {</span>
<span class="source-line-no">4361</span><span id="line-4361"> boolean more = s.next(results, scannerContext);</span>
<span class="source-line-no">4362</span><span id="line-4362"> if ((index &gt;&gt; 1) &lt; 5) {</span>
<span class="source-line-no">4363</span><span id="line-4363"> if (index % 2 == 0) {</span>
<span class="source-line-no">4364</span><span id="line-4364"> assertEquals(3, results.size());</span>
<span class="source-line-no">4365</span><span id="line-4365"> } else {</span>
<span class="source-line-no">4366</span><span id="line-4366"> assertEquals(1, results.size());</span>
<span class="source-line-no">4367</span><span id="line-4367"> }</span>
<span class="source-line-no">4368</span><span id="line-4368"> } else {</span>
<span class="source-line-no">4369</span><span id="line-4369"> assertEquals(1, results.size());</span>
<span class="source-line-no">4370</span><span id="line-4370"> }</span>
<span class="source-line-no">4371</span><span id="line-4371"> results.clear();</span>
<span class="source-line-no">4372</span><span id="line-4372"> index++;</span>
<span class="source-line-no">4373</span><span id="line-4373"> if (!more) {</span>
<span class="source-line-no">4374</span><span id="line-4374"> break;</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"> }</span>
<span class="source-line-no">4379</span><span id="line-4379"></span>
<span class="source-line-no">4380</span><span id="line-4380"> @Test</span>
<span class="source-line-no">4381</span><span id="line-4381"> public void testScannerOperationId() throws IOException {</span>
<span class="source-line-no">4382</span><span id="line-4382"> region = initHRegion(tableName, method, CONF, COLUMN_FAMILY_BYTES);</span>
<span class="source-line-no">4383</span><span id="line-4383"> Scan scan = new Scan();</span>
<span class="source-line-no">4384</span><span id="line-4384"> try (RegionScanner scanner = region.getScanner(scan)) {</span>
<span class="source-line-no">4385</span><span id="line-4385"> assertNull(scanner.getOperationId());</span>
<span class="source-line-no">4386</span><span id="line-4386"> }</span>
<span class="source-line-no">4387</span><span id="line-4387"></span>
<span class="source-line-no">4388</span><span id="line-4388"> String operationId = "test_operation_id_0101";</span>
<span class="source-line-no">4389</span><span id="line-4389"> scan = new Scan().setId(operationId);</span>
<span class="source-line-no">4390</span><span id="line-4390"> try (RegionScanner scanner = region.getScanner(scan)) {</span>
<span class="source-line-no">4391</span><span id="line-4391"> assertEquals(operationId, scanner.getOperationId());</span>
<span class="source-line-no">4392</span><span id="line-4392"> }</span>
<span class="source-line-no">4393</span><span id="line-4393"></span>
<span class="source-line-no">4394</span><span id="line-4394"> HBaseTestingUtil.closeRegionAndWAL(this.region);</span>
<span class="source-line-no">4395</span><span id="line-4395"> }</span>
<span class="source-line-no">4396</span><span id="line-4396"></span>
<span class="source-line-no">4397</span><span id="line-4397"> /**</span>
<span class="source-line-no">4398</span><span id="line-4398"> * Write an HFile block full with Cells whose qualifier that are identical between 0 and</span>
<span class="source-line-no">4399</span><span id="line-4399"> * Short.MAX_VALUE. See HBASE-13329.</span>
<span class="source-line-no">4400</span><span id="line-4400"> */</span>
<span class="source-line-no">4401</span><span id="line-4401"> @Test</span>
<span class="source-line-no">4402</span><span id="line-4402"> public void testLongQualifier() throws Exception {</span>
<span class="source-line-no">4403</span><span id="line-4403"> byte[] family = Bytes.toBytes("family");</span>
<span class="source-line-no">4404</span><span id="line-4404"> this.region = initHRegion(tableName, method, CONF, family);</span>
<span class="source-line-no">4405</span><span id="line-4405"> byte[] q = new byte[Short.MAX_VALUE + 2];</span>
<span class="source-line-no">4406</span><span id="line-4406"> Arrays.fill(q, 0, q.length - 1, (byte) 42);</span>
<span class="source-line-no">4407</span><span id="line-4407"> for (byte i = 0; i &lt; 10; i++) {</span>
<span class="source-line-no">4408</span><span id="line-4408"> Put p = new Put(Bytes.toBytes("row"));</span>
<span class="source-line-no">4409</span><span id="line-4409"> // qualifiers that differ past Short.MAX_VALUE</span>
<span class="source-line-no">4410</span><span id="line-4410"> q[q.length - 1] = i;</span>
<span class="source-line-no">4411</span><span id="line-4411"> p.addColumn(family, q, q);</span>
<span class="source-line-no">4412</span><span id="line-4412"> region.put(p);</span>
<span class="source-line-no">4413</span><span id="line-4413"> }</span>
<span class="source-line-no">4414</span><span id="line-4414"> region.flush(false);</span>
<span class="source-line-no">4415</span><span id="line-4415"> }</span>
<span class="source-line-no">4416</span><span id="line-4416"></span>
<span class="source-line-no">4417</span><span id="line-4417"> /**</span>
<span class="source-line-no">4418</span><span id="line-4418"> * Flushes the cache in a thread while scanning. The tests verify that the scan is coherent - e.g.</span>
<span class="source-line-no">4419</span><span id="line-4419"> * the returned results are always of the same or later update as the previous results. scan /</span>
<span class="source-line-no">4420</span><span id="line-4420"> * compact thread join</span>
<span class="source-line-no">4421</span><span id="line-4421"> */</span>
<span class="source-line-no">4422</span><span id="line-4422"> @Test</span>
<span class="source-line-no">4423</span><span id="line-4423"> public void testFlushCacheWhileScanning() throws IOException, InterruptedException {</span>
<span class="source-line-no">4424</span><span id="line-4424"> byte[] family = Bytes.toBytes("family");</span>
<span class="source-line-no">4425</span><span id="line-4425"> int numRows = 1000;</span>
<span class="source-line-no">4426</span><span id="line-4426"> int flushAndScanInterval = 10;</span>
<span class="source-line-no">4427</span><span id="line-4427"> int compactInterval = 10 * flushAndScanInterval;</span>
<span class="source-line-no">4428</span><span id="line-4428"></span>
<span class="source-line-no">4429</span><span id="line-4429"> this.region = initHRegion(tableName, method, CONF, family);</span>
<span class="source-line-no">4430</span><span id="line-4430"> FlushThread flushThread = new FlushThread();</span>
<span class="source-line-no">4431</span><span id="line-4431"> try {</span>
<span class="source-line-no">4432</span><span id="line-4432"> flushThread.start();</span>
<span class="source-line-no">4433</span><span id="line-4433"></span>
<span class="source-line-no">4434</span><span id="line-4434"> Scan scan = new Scan();</span>
<span class="source-line-no">4435</span><span id="line-4435"> scan.addFamily(family);</span>
<span class="source-line-no">4436</span><span id="line-4436"> scan.setFilter(new SingleColumnValueFilter(family, qual1, CompareOperator.EQUAL,</span>
<span class="source-line-no">4437</span><span id="line-4437"> new BinaryComparator(Bytes.toBytes(5L))));</span>
<span class="source-line-no">4438</span><span id="line-4438"></span>
<span class="source-line-no">4439</span><span id="line-4439"> int expectedCount = 0;</span>
<span class="source-line-no">4440</span><span id="line-4440"> List&lt;Cell&gt; res = new ArrayList&lt;&gt;();</span>
<span class="source-line-no">4441</span><span id="line-4441"></span>
<span class="source-line-no">4442</span><span id="line-4442"> boolean toggle = true;</span>
<span class="source-line-no">4443</span><span id="line-4443"> for (long i = 0; i &lt; numRows; i++) {</span>
<span class="source-line-no">4444</span><span id="line-4444"> Put put = new Put(Bytes.toBytes(i));</span>
<span class="source-line-no">4445</span><span id="line-4445"> put.setDurability(Durability.SKIP_WAL);</span>
<span class="source-line-no">4446</span><span id="line-4446"> put.addColumn(family, qual1, Bytes.toBytes(i % 10));</span>
<span class="source-line-no">4447</span><span id="line-4447"> region.put(put);</span>
<span class="source-line-no">4448</span><span id="line-4448"></span>
<span class="source-line-no">4449</span><span id="line-4449"> if (i != 0 &amp;&amp; i % compactInterval == 0) {</span>
<span class="source-line-no">4450</span><span id="line-4450"> LOG.debug("iteration = " + i + " ts=" + EnvironmentEdgeManager.currentTime());</span>
<span class="source-line-no">4451</span><span id="line-4451"> region.compact(true);</span>
<span class="source-line-no">4452</span><span id="line-4452"> }</span>
<span class="source-line-no">4453</span><span id="line-4453"></span>
<span class="source-line-no">4454</span><span id="line-4454"> if (i % 10 == 5L) {</span>
<span class="source-line-no">4455</span><span id="line-4455"> expectedCount++;</span>
<span class="source-line-no">4456</span><span id="line-4456"> }</span>
<span class="source-line-no">4457</span><span id="line-4457"></span>
<span class="source-line-no">4458</span><span id="line-4458"> if (i != 0 &amp;&amp; i % flushAndScanInterval == 0) {</span>
<span class="source-line-no">4459</span><span id="line-4459"> res.clear();</span>
<span class="source-line-no">4460</span><span id="line-4460"> try (InternalScanner scanner = region.getScanner(scan)) {</span>
<span class="source-line-no">4461</span><span id="line-4461"> if (toggle) {</span>
<span class="source-line-no">4462</span><span id="line-4462"> flushThread.flush();</span>
<span class="source-line-no">4463</span><span id="line-4463"> }</span>
<span class="source-line-no">4464</span><span id="line-4464"> while (scanner.next(res)) {</span>
<span class="source-line-no">4465</span><span id="line-4465"> // ignore</span>
<span class="source-line-no">4466</span><span id="line-4466"> }</span>
<span class="source-line-no">4467</span><span id="line-4467"> }</span>
<span class="source-line-no">4468</span><span id="line-4468"> if (!toggle) {</span>
<span class="source-line-no">4469</span><span id="line-4469"> flushThread.flush();</span>
<span class="source-line-no">4470</span><span id="line-4470"> }</span>
<span class="source-line-no">4471</span><span id="line-4471"> assertEquals(</span>
<span class="source-line-no">4472</span><span id="line-4472"> "toggle=" + toggle + "i=" + i + " ts=" + EnvironmentEdgeManager.currentTime(),</span>
<span class="source-line-no">4473</span><span id="line-4473"> expectedCount, res.size());</span>
<span class="source-line-no">4474</span><span id="line-4474"> toggle = !toggle;</span>
<span class="source-line-no">4475</span><span id="line-4475"> }</span>
<span class="source-line-no">4476</span><span id="line-4476"> }</span>
<span class="source-line-no">4477</span><span id="line-4477"></span>
<span class="source-line-no">4478</span><span id="line-4478"> } finally {</span>
<span class="source-line-no">4479</span><span id="line-4479"> try {</span>
<span class="source-line-no">4480</span><span id="line-4480"> flushThread.done();</span>
<span class="source-line-no">4481</span><span id="line-4481"> flushThread.join();</span>
<span class="source-line-no">4482</span><span id="line-4482"> flushThread.checkNoError();</span>
<span class="source-line-no">4483</span><span id="line-4483"> } catch (InterruptedException ie) {</span>
<span class="source-line-no">4484</span><span id="line-4484"> LOG.warn("Caught exception when joining with flushThread", ie);</span>
<span class="source-line-no">4485</span><span id="line-4485"> }</span>
<span class="source-line-no">4486</span><span id="line-4486"> HBaseTestingUtil.closeRegionAndWAL(this.region);</span>
<span class="source-line-no">4487</span><span id="line-4487"> this.region = null;</span>
<span class="source-line-no">4488</span><span id="line-4488"> }</span>
<span class="source-line-no">4489</span><span id="line-4489"> }</span>
<span class="source-line-no">4490</span><span id="line-4490"></span>
<span class="source-line-no">4491</span><span id="line-4491"> protected class FlushThread extends Thread {</span>
<span class="source-line-no">4492</span><span id="line-4492"> private volatile boolean done;</span>
<span class="source-line-no">4493</span><span id="line-4493"> private Throwable error = null;</span>
<span class="source-line-no">4494</span><span id="line-4494"></span>
<span class="source-line-no">4495</span><span id="line-4495"> FlushThread() {</span>
<span class="source-line-no">4496</span><span id="line-4496"> super("FlushThread");</span>
<span class="source-line-no">4497</span><span id="line-4497"> }</span>
<span class="source-line-no">4498</span><span id="line-4498"></span>
<span class="source-line-no">4499</span><span id="line-4499"> public void done() {</span>
<span class="source-line-no">4500</span><span id="line-4500"> done = true;</span>
<span class="source-line-no">4501</span><span id="line-4501"> synchronized (this) {</span>
<span class="source-line-no">4502</span><span id="line-4502"> interrupt();</span>
<span class="source-line-no">4503</span><span id="line-4503"> }</span>
<span class="source-line-no">4504</span><span id="line-4504"> }</span>
<span class="source-line-no">4505</span><span id="line-4505"></span>
<span class="source-line-no">4506</span><span id="line-4506"> public void checkNoError() {</span>
<span class="source-line-no">4507</span><span id="line-4507"> if (error != null) {</span>
<span class="source-line-no">4508</span><span id="line-4508"> assertNull(error);</span>
<span class="source-line-no">4509</span><span id="line-4509"> }</span>
<span class="source-line-no">4510</span><span id="line-4510"> }</span>
<span class="source-line-no">4511</span><span id="line-4511"></span>
<span class="source-line-no">4512</span><span id="line-4512"> @Override</span>
<span class="source-line-no">4513</span><span id="line-4513"> public void run() {</span>
<span class="source-line-no">4514</span><span id="line-4514"> done = false;</span>
<span class="source-line-no">4515</span><span id="line-4515"> while (!done) {</span>
<span class="source-line-no">4516</span><span id="line-4516"> synchronized (this) {</span>
<span class="source-line-no">4517</span><span id="line-4517"> try {</span>
<span class="source-line-no">4518</span><span id="line-4518"> wait();</span>
<span class="source-line-no">4519</span><span id="line-4519"> } catch (InterruptedException ignored) {</span>
<span class="source-line-no">4520</span><span id="line-4520"> if (done) {</span>
<span class="source-line-no">4521</span><span id="line-4521"> break;</span>
<span class="source-line-no">4522</span><span id="line-4522"> }</span>
<span class="source-line-no">4523</span><span id="line-4523"> }</span>
<span class="source-line-no">4524</span><span id="line-4524"> }</span>
<span class="source-line-no">4525</span><span id="line-4525"> try {</span>
<span class="source-line-no">4526</span><span id="line-4526"> region.flush(true);</span>
<span class="source-line-no">4527</span><span id="line-4527"> } catch (IOException e) {</span>
<span class="source-line-no">4528</span><span id="line-4528"> if (!done) {</span>
<span class="source-line-no">4529</span><span id="line-4529"> LOG.error("Error while flushing cache", e);</span>
<span class="source-line-no">4530</span><span id="line-4530"> error = e;</span>
<span class="source-line-no">4531</span><span id="line-4531"> }</span>
<span class="source-line-no">4532</span><span id="line-4532"> break;</span>
<span class="source-line-no">4533</span><span id="line-4533"> } catch (Throwable t) {</span>
<span class="source-line-no">4534</span><span id="line-4534"> LOG.error("Uncaught exception", t);</span>
<span class="source-line-no">4535</span><span id="line-4535"> throw t;</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"> }</span>
<span class="source-line-no">4539</span><span id="line-4539"></span>
<span class="source-line-no">4540</span><span id="line-4540"> public void flush() {</span>
<span class="source-line-no">4541</span><span id="line-4541"> synchronized (this) {</span>
<span class="source-line-no">4542</span><span id="line-4542"> notify();</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"></span>
<span class="source-line-no">4547</span><span id="line-4547"> /**</span>
<span class="source-line-no">4548</span><span id="line-4548"> * So can be overridden in subclasses.</span>
<span class="source-line-no">4549</span><span id="line-4549"> */</span>
<span class="source-line-no">4550</span><span id="line-4550"> protected int getNumQualifiersForTestWritesWhileScanning() {</span>
<span class="source-line-no">4551</span><span id="line-4551"> return 100;</span>
<span class="source-line-no">4552</span><span id="line-4552"> }</span>
<span class="source-line-no">4553</span><span id="line-4553"></span>
<span class="source-line-no">4554</span><span id="line-4554"> /**</span>
<span class="source-line-no">4555</span><span id="line-4555"> * So can be overridden in subclasses.</span>
<span class="source-line-no">4556</span><span id="line-4556"> */</span>
<span class="source-line-no">4557</span><span id="line-4557"> protected int getTestCountForTestWritesWhileScanning() {</span>
<span class="source-line-no">4558</span><span id="line-4558"> return 100;</span>
<span class="source-line-no">4559</span><span id="line-4559"> }</span>
<span class="source-line-no">4560</span><span id="line-4560"></span>
<span class="source-line-no">4561</span><span id="line-4561"> /**</span>
<span class="source-line-no">4562</span><span id="line-4562"> * Writes very wide records and scans for the latest every time.. Flushes and compacts the region</span>
<span class="source-line-no">4563</span><span id="line-4563"> * every now and then to keep things realistic. by flush / scan / compaction when joining threads</span>
<span class="source-line-no">4564</span><span id="line-4564"> */</span>
<span class="source-line-no">4565</span><span id="line-4565"> @Test</span>
<span class="source-line-no">4566</span><span id="line-4566"> public void testWritesWhileScanning() throws IOException, InterruptedException {</span>
<span class="source-line-no">4567</span><span id="line-4567"> int testCount = getTestCountForTestWritesWhileScanning();</span>
<span class="source-line-no">4568</span><span id="line-4568"> int numRows = 1;</span>
<span class="source-line-no">4569</span><span id="line-4569"> int numFamilies = 10;</span>
<span class="source-line-no">4570</span><span id="line-4570"> int numQualifiers = getNumQualifiersForTestWritesWhileScanning();</span>
<span class="source-line-no">4571</span><span id="line-4571"> int flushInterval = 7;</span>
<span class="source-line-no">4572</span><span id="line-4572"> int compactInterval = 5 * flushInterval;</span>
<span class="source-line-no">4573</span><span id="line-4573"> byte[][] families = new byte[numFamilies][];</span>
<span class="source-line-no">4574</span><span id="line-4574"> for (int i = 0; i &lt; numFamilies; i++) {</span>
<span class="source-line-no">4575</span><span id="line-4575"> families[i] = Bytes.toBytes("family" + i);</span>
<span class="source-line-no">4576</span><span id="line-4576"> }</span>
<span class="source-line-no">4577</span><span id="line-4577"> byte[][] qualifiers = new byte[numQualifiers][];</span>
<span class="source-line-no">4578</span><span id="line-4578"> for (int i = 0; i &lt; numQualifiers; i++) {</span>
<span class="source-line-no">4579</span><span id="line-4579"> qualifiers[i] = Bytes.toBytes("qual" + i);</span>
<span class="source-line-no">4580</span><span id="line-4580"> }</span>
<span class="source-line-no">4581</span><span id="line-4581"></span>
<span class="source-line-no">4582</span><span id="line-4582"> this.region = initHRegion(tableName, method, CONF, families);</span>
<span class="source-line-no">4583</span><span id="line-4583"> FlushThread flushThread = new FlushThread();</span>
<span class="source-line-no">4584</span><span id="line-4584"> PutThread putThread = new PutThread(numRows, families, qualifiers);</span>
<span class="source-line-no">4585</span><span id="line-4585"> try {</span>
<span class="source-line-no">4586</span><span id="line-4586"> putThread.start();</span>
<span class="source-line-no">4587</span><span id="line-4587"> putThread.waitForFirstPut();</span>
<span class="source-line-no">4588</span><span id="line-4588"></span>
<span class="source-line-no">4589</span><span id="line-4589"> flushThread.start();</span>
<span class="source-line-no">4590</span><span id="line-4590"></span>
<span class="source-line-no">4591</span><span id="line-4591"> Scan scan = new Scan().withStartRow(Bytes.toBytes("row0")).withStopRow(Bytes.toBytes("row1"));</span>
<span class="source-line-no">4592</span><span id="line-4592"></span>
<span class="source-line-no">4593</span><span id="line-4593"> int expectedCount = numFamilies * numQualifiers;</span>
<span class="source-line-no">4594</span><span id="line-4594"> List&lt;Cell&gt; res = new ArrayList&lt;&gt;();</span>
<span class="source-line-no">4595</span><span id="line-4595"></span>
<span class="source-line-no">4596</span><span id="line-4596"> long prevTimestamp = 0L;</span>
<span class="source-line-no">4597</span><span id="line-4597"> for (int i = 0; i &lt; testCount; i++) {</span>
<span class="source-line-no">4598</span><span id="line-4598"></span>
<span class="source-line-no">4599</span><span id="line-4599"> if (i != 0 &amp;&amp; i % compactInterval == 0) {</span>
<span class="source-line-no">4600</span><span id="line-4600"> region.compact(true);</span>
<span class="source-line-no">4601</span><span id="line-4601"> for (HStore store : region.getStores()) {</span>
<span class="source-line-no">4602</span><span id="line-4602"> store.closeAndArchiveCompactedFiles();</span>
<span class="source-line-no">4603</span><span id="line-4603"> }</span>
<span class="source-line-no">4604</span><span id="line-4604"> }</span>
<span class="source-line-no">4605</span><span id="line-4605"></span>
<span class="source-line-no">4606</span><span id="line-4606"> if (i != 0 &amp;&amp; i % flushInterval == 0) {</span>
<span class="source-line-no">4607</span><span id="line-4607"> flushThread.flush();</span>
<span class="source-line-no">4608</span><span id="line-4608"> }</span>
<span class="source-line-no">4609</span><span id="line-4609"></span>
<span class="source-line-no">4610</span><span id="line-4610"> boolean previousEmpty = res.isEmpty();</span>
<span class="source-line-no">4611</span><span id="line-4611"> res.clear();</span>
<span class="source-line-no">4612</span><span id="line-4612"> try (InternalScanner scanner = region.getScanner(scan)) {</span>
<span class="source-line-no">4613</span><span id="line-4613"> boolean moreRows;</span>
<span class="source-line-no">4614</span><span id="line-4614"> do {</span>
<span class="source-line-no">4615</span><span id="line-4615"> moreRows = scanner.next(res);</span>
<span class="source-line-no">4616</span><span id="line-4616"> } while (moreRows);</span>
<span class="source-line-no">4617</span><span id="line-4617"> }</span>
<span class="source-line-no">4618</span><span id="line-4618"> if (!res.isEmpty() || !previousEmpty || i &gt; compactInterval) {</span>
<span class="source-line-no">4619</span><span id="line-4619"> assertEquals("i=" + i, expectedCount, res.size());</span>
<span class="source-line-no">4620</span><span id="line-4620"> long timestamp = res.get(0).getTimestamp();</span>
<span class="source-line-no">4621</span><span id="line-4621"> assertTrue("Timestamps were broke: " + timestamp + " prev: " + prevTimestamp,</span>
<span class="source-line-no">4622</span><span id="line-4622"> timestamp &gt;= prevTimestamp);</span>
<span class="source-line-no">4623</span><span id="line-4623"> prevTimestamp = timestamp;</span>
<span class="source-line-no">4624</span><span id="line-4624"> }</span>
<span class="source-line-no">4625</span><span id="line-4625"> }</span>
<span class="source-line-no">4626</span><span id="line-4626"></span>
<span class="source-line-no">4627</span><span id="line-4627"> putThread.done();</span>
<span class="source-line-no">4628</span><span id="line-4628"></span>
<span class="source-line-no">4629</span><span id="line-4629"> region.flush(true);</span>
<span class="source-line-no">4630</span><span id="line-4630"></span>
<span class="source-line-no">4631</span><span id="line-4631"> } finally {</span>
<span class="source-line-no">4632</span><span id="line-4632"> try {</span>
<span class="source-line-no">4633</span><span id="line-4633"> flushThread.done();</span>
<span class="source-line-no">4634</span><span id="line-4634"> flushThread.join();</span>
<span class="source-line-no">4635</span><span id="line-4635"> flushThread.checkNoError();</span>
<span class="source-line-no">4636</span><span id="line-4636"></span>
<span class="source-line-no">4637</span><span id="line-4637"> putThread.join();</span>
<span class="source-line-no">4638</span><span id="line-4638"> putThread.checkNoError();</span>
<span class="source-line-no">4639</span><span id="line-4639"> } catch (InterruptedException ie) {</span>
<span class="source-line-no">4640</span><span id="line-4640"> LOG.warn("Caught exception when joining with flushThread", ie);</span>
<span class="source-line-no">4641</span><span id="line-4641"> }</span>
<span class="source-line-no">4642</span><span id="line-4642"></span>
<span class="source-line-no">4643</span><span id="line-4643"> try {</span>
<span class="source-line-no">4644</span><span id="line-4644"> HBaseTestingUtil.closeRegionAndWAL(this.region);</span>
<span class="source-line-no">4645</span><span id="line-4645"> } catch (DroppedSnapshotException dse) {</span>
<span class="source-line-no">4646</span><span id="line-4646"> // We could get this on way out because we interrupt the background flusher and it could</span>
<span class="source-line-no">4647</span><span id="line-4647"> // fail anywhere causing a DSE over in the background flusher... only it is not properly</span>
<span class="source-line-no">4648</span><span id="line-4648"> // dealt with so could still be memory hanging out when we get to here -- memory we can't</span>
<span class="source-line-no">4649</span><span id="line-4649"> // flush because the accounting is 'off' since original DSE.</span>
<span class="source-line-no">4650</span><span id="line-4650"> }</span>
<span class="source-line-no">4651</span><span id="line-4651"> this.region = null;</span>
<span class="source-line-no">4652</span><span id="line-4652"> }</span>
<span class="source-line-no">4653</span><span id="line-4653"> }</span>
<span class="source-line-no">4654</span><span id="line-4654"></span>
<span class="source-line-no">4655</span><span id="line-4655"> @Test</span>
<span class="source-line-no">4656</span><span id="line-4656"> public void testCloseAndArchiveCompactedFiles() throws IOException {</span>
<span class="source-line-no">4657</span><span id="line-4657"> byte[] CF1 = Bytes.toBytes("CF1");</span>
<span class="source-line-no">4658</span><span id="line-4658"> byte[] CF2 = Bytes.toBytes("CF2");</span>
<span class="source-line-no">4659</span><span id="line-4659"> this.region = initHRegion(tableName, method, CONF, CF1, CF2);</span>
<span class="source-line-no">4660</span><span id="line-4660"> for (int i = 0; i &lt; 2; i++) {</span>
<span class="source-line-no">4661</span><span id="line-4661"> int index = i;</span>
<span class="source-line-no">4662</span><span id="line-4662"> Put put =</span>
<span class="source-line-no">4663</span><span id="line-4663"> new Put(Bytes.toBytes(index)).addColumn(CF1, Bytes.toBytes("q"), Bytes.toBytes(index));</span>
<span class="source-line-no">4664</span><span id="line-4664"> region.put(put);</span>
<span class="source-line-no">4665</span><span id="line-4665"> region.flush(true);</span>
<span class="source-line-no">4666</span><span id="line-4666"> }</span>
<span class="source-line-no">4667</span><span id="line-4667"></span>
<span class="source-line-no">4668</span><span id="line-4668"> region.compact(true);</span>
<span class="source-line-no">4669</span><span id="line-4669"></span>
<span class="source-line-no">4670</span><span id="line-4670"> HStore store1 = region.getStore(CF1);</span>
<span class="source-line-no">4671</span><span id="line-4671"> HStore store2 = region.getStore(CF2);</span>
<span class="source-line-no">4672</span><span id="line-4672"> store1.closeAndArchiveCompactedFiles();</span>
<span class="source-line-no">4673</span><span id="line-4673"> store2.closeAndArchiveCompactedFiles();</span>
<span class="source-line-no">4674</span><span id="line-4674"></span>
<span class="source-line-no">4675</span><span id="line-4675"> int storefilesCount = region.getStores().stream().mapToInt(Store::getStorefilesCount).sum();</span>
<span class="source-line-no">4676</span><span id="line-4676"> assertTrue(storefilesCount == 1);</span>
<span class="source-line-no">4677</span><span id="line-4677"></span>
<span class="source-line-no">4678</span><span id="line-4678"> FileSystem fs = region.getRegionFileSystem().getFileSystem();</span>
<span class="source-line-no">4679</span><span id="line-4679"> Configuration conf = region.getReadOnlyConfiguration();</span>
<span class="source-line-no">4680</span><span id="line-4680"> RegionInfo regionInfo = region.getRegionInfo();</span>
<span class="source-line-no">4681</span><span id="line-4681"> Path store1ArchiveDir = HFileArchiveUtil.getStoreArchivePath(conf, regionInfo, CF1);</span>
<span class="source-line-no">4682</span><span id="line-4682"> assertTrue(fs.exists(store1ArchiveDir));</span>
<span class="source-line-no">4683</span><span id="line-4683"> // The archived dir of CF2 does not exist because this column family has no data at all</span>
<span class="source-line-no">4684</span><span id="line-4684"> Path store2ArchiveDir = HFileArchiveUtil.getStoreArchivePath(conf, regionInfo, CF2);</span>
<span class="source-line-no">4685</span><span id="line-4685"> assertFalse(fs.exists(store2ArchiveDir));</span>
<span class="source-line-no">4686</span><span id="line-4686"> }</span>
<span class="source-line-no">4687</span><span id="line-4687"></span>
<span class="source-line-no">4688</span><span id="line-4688"> protected class PutThread extends Thread {</span>
<span class="source-line-no">4689</span><span id="line-4689"> private volatile boolean done;</span>
<span class="source-line-no">4690</span><span id="line-4690"> private volatile int numPutsFinished = 0;</span>
<span class="source-line-no">4691</span><span id="line-4691"></span>
<span class="source-line-no">4692</span><span id="line-4692"> private Throwable error = null;</span>
<span class="source-line-no">4693</span><span id="line-4693"> private int numRows;</span>
<span class="source-line-no">4694</span><span id="line-4694"> private byte[][] families;</span>
<span class="source-line-no">4695</span><span id="line-4695"> private byte[][] qualifiers;</span>
<span class="source-line-no">4696</span><span id="line-4696"></span>
<span class="source-line-no">4697</span><span id="line-4697"> private PutThread(int numRows, byte[][] families, byte[][] qualifiers) {</span>
<span class="source-line-no">4698</span><span id="line-4698"> super("PutThread");</span>
<span class="source-line-no">4699</span><span id="line-4699"> this.numRows = numRows;</span>
<span class="source-line-no">4700</span><span id="line-4700"> this.families = families;</span>
<span class="source-line-no">4701</span><span id="line-4701"> this.qualifiers = qualifiers;</span>
<span class="source-line-no">4702</span><span id="line-4702"> }</span>
<span class="source-line-no">4703</span><span id="line-4703"></span>
<span class="source-line-no">4704</span><span id="line-4704"> /**</span>
<span class="source-line-no">4705</span><span id="line-4705"> * Block calling thread until this instance of PutThread has put at least one row.</span>
<span class="source-line-no">4706</span><span id="line-4706"> */</span>
<span class="source-line-no">4707</span><span id="line-4707"> public void waitForFirstPut() throws InterruptedException {</span>
<span class="source-line-no">4708</span><span id="line-4708"> // wait until put thread actually puts some data</span>
<span class="source-line-no">4709</span><span id="line-4709"> while (isAlive() &amp;&amp; numPutsFinished == 0) {</span>
<span class="source-line-no">4710</span><span id="line-4710"> checkNoError();</span>
<span class="source-line-no">4711</span><span id="line-4711"> Thread.sleep(50);</span>
<span class="source-line-no">4712</span><span id="line-4712"> }</span>
<span class="source-line-no">4713</span><span id="line-4713"> }</span>
<span class="source-line-no">4714</span><span id="line-4714"></span>
<span class="source-line-no">4715</span><span id="line-4715"> public void done() {</span>
<span class="source-line-no">4716</span><span id="line-4716"> done = true;</span>
<span class="source-line-no">4717</span><span id="line-4717"> synchronized (this) {</span>
<span class="source-line-no">4718</span><span id="line-4718"> interrupt();</span>
<span class="source-line-no">4719</span><span id="line-4719"> }</span>
<span class="source-line-no">4720</span><span id="line-4720"> }</span>
<span class="source-line-no">4721</span><span id="line-4721"></span>
<span class="source-line-no">4722</span><span id="line-4722"> public void checkNoError() {</span>
<span class="source-line-no">4723</span><span id="line-4723"> if (error != null) {</span>
<span class="source-line-no">4724</span><span id="line-4724"> assertNull(error);</span>
<span class="source-line-no">4725</span><span id="line-4725"> }</span>
<span class="source-line-no">4726</span><span id="line-4726"> }</span>
<span class="source-line-no">4727</span><span id="line-4727"></span>
<span class="source-line-no">4728</span><span id="line-4728"> @Override</span>
<span class="source-line-no">4729</span><span id="line-4729"> public void run() {</span>
<span class="source-line-no">4730</span><span id="line-4730"> done = false;</span>
<span class="source-line-no">4731</span><span id="line-4731"> while (!done) {</span>
<span class="source-line-no">4732</span><span id="line-4732"> try {</span>
<span class="source-line-no">4733</span><span id="line-4733"> for (int r = 0; r &lt; numRows; r++) {</span>
<span class="source-line-no">4734</span><span id="line-4734"> byte[] row = Bytes.toBytes("row" + r);</span>
<span class="source-line-no">4735</span><span id="line-4735"> Put put = new Put(row);</span>
<span class="source-line-no">4736</span><span id="line-4736"> put.setDurability(Durability.SKIP_WAL);</span>
<span class="source-line-no">4737</span><span id="line-4737"> byte[] value = Bytes.toBytes(String.valueOf(numPutsFinished));</span>
<span class="source-line-no">4738</span><span id="line-4738"> for (byte[] family : families) {</span>
<span class="source-line-no">4739</span><span id="line-4739"> for (byte[] qualifier : qualifiers) {</span>
<span class="source-line-no">4740</span><span id="line-4740"> put.addColumn(family, qualifier, numPutsFinished, value);</span>
<span class="source-line-no">4741</span><span id="line-4741"> }</span>
<span class="source-line-no">4742</span><span id="line-4742"> }</span>
<span class="source-line-no">4743</span><span id="line-4743"> region.put(put);</span>
<span class="source-line-no">4744</span><span id="line-4744"> numPutsFinished++;</span>
<span class="source-line-no">4745</span><span id="line-4745"> if (numPutsFinished &gt; 0 &amp;&amp; numPutsFinished % 47 == 0) {</span>
<span class="source-line-no">4746</span><span id="line-4746"> LOG.debug("put iteration = {}", numPutsFinished);</span>
<span class="source-line-no">4747</span><span id="line-4747"> Delete delete = new Delete(row, (long) numPutsFinished - 30);</span>
<span class="source-line-no">4748</span><span id="line-4748"> region.delete(delete);</span>
<span class="source-line-no">4749</span><span id="line-4749"> }</span>
<span class="source-line-no">4750</span><span id="line-4750"> numPutsFinished++;</span>
<span class="source-line-no">4751</span><span id="line-4751"> }</span>
<span class="source-line-no">4752</span><span id="line-4752"> } catch (InterruptedIOException e) {</span>
<span class="source-line-no">4753</span><span id="line-4753"> // This is fine. It means we are done, or didn't get the lock on time</span>
<span class="source-line-no">4754</span><span id="line-4754"> LOG.info("Interrupted", e);</span>
<span class="source-line-no">4755</span><span id="line-4755"> } catch (IOException e) {</span>
<span class="source-line-no">4756</span><span id="line-4756"> LOG.error("Error while putting records", e);</span>
<span class="source-line-no">4757</span><span id="line-4757"> error = e;</span>
<span class="source-line-no">4758</span><span id="line-4758"> break;</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"></span>
<span class="source-line-no">4766</span><span id="line-4766"> /**</span>
<span class="source-line-no">4767</span><span id="line-4767"> * Writes very wide records and gets the latest row every time.. Flushes and compacts the region</span>
<span class="source-line-no">4768</span><span id="line-4768"> * aggressivly to catch issues. by flush / scan / compaction when joining threads</span>
<span class="source-line-no">4769</span><span id="line-4769"> */</span>
<span class="source-line-no">4770</span><span id="line-4770"> @Test</span>
<span class="source-line-no">4771</span><span id="line-4771"> public void testWritesWhileGetting() throws Exception {</span>
<span class="source-line-no">4772</span><span id="line-4772"> int testCount = 50;</span>
<span class="source-line-no">4773</span><span id="line-4773"> int numRows = 1;</span>
<span class="source-line-no">4774</span><span id="line-4774"> int numFamilies = 10;</span>
<span class="source-line-no">4775</span><span id="line-4775"> int numQualifiers = 100;</span>
<span class="source-line-no">4776</span><span id="line-4776"> int compactInterval = 100;</span>
<span class="source-line-no">4777</span><span id="line-4777"> byte[][] families = new byte[numFamilies][];</span>
<span class="source-line-no">4778</span><span id="line-4778"> for (int i = 0; i &lt; numFamilies; i++) {</span>
<span class="source-line-no">4779</span><span id="line-4779"> families[i] = Bytes.toBytes("family" + i);</span>
<span class="source-line-no">4780</span><span id="line-4780"> }</span>
<span class="source-line-no">4781</span><span id="line-4781"> byte[][] qualifiers = new byte[numQualifiers][];</span>
<span class="source-line-no">4782</span><span id="line-4782"> for (int i = 0; i &lt; numQualifiers; i++) {</span>
<span class="source-line-no">4783</span><span id="line-4783"> qualifiers[i] = Bytes.toBytes("qual" + i);</span>
<span class="source-line-no">4784</span><span id="line-4784"> }</span>
<span class="source-line-no">4785</span><span id="line-4785"></span>
<span class="source-line-no">4786</span><span id="line-4786"> // This test flushes constantly and can cause many files to be created,</span>
<span class="source-line-no">4787</span><span id="line-4787"> // possibly</span>
<span class="source-line-no">4788</span><span id="line-4788"> // extending over the ulimit. Make sure compactions are aggressive in</span>
<span class="source-line-no">4789</span><span id="line-4789"> // reducing</span>
<span class="source-line-no">4790</span><span id="line-4790"> // the number of HFiles created.</span>
<span class="source-line-no">4791</span><span id="line-4791"> Configuration conf = HBaseConfiguration.create(CONF);</span>
<span class="source-line-no">4792</span><span id="line-4792"> conf.setInt("hbase.hstore.compaction.min", 1);</span>
<span class="source-line-no">4793</span><span id="line-4793"> conf.setInt("hbase.hstore.compaction.max", 1000);</span>
<span class="source-line-no">4794</span><span id="line-4794"> this.region = initHRegion(tableName, method, conf, families);</span>
<span class="source-line-no">4795</span><span id="line-4795"> PutThread putThread = null;</span>
<span class="source-line-no">4796</span><span id="line-4796"> MultithreadedTestUtil.TestContext ctx = new MultithreadedTestUtil.TestContext(conf);</span>
<span class="source-line-no">4797</span><span id="line-4797"> try {</span>
<span class="source-line-no">4798</span><span id="line-4798"> putThread = new PutThread(numRows, families, qualifiers);</span>
<span class="source-line-no">4799</span><span id="line-4799"> putThread.start();</span>
<span class="source-line-no">4800</span><span id="line-4800"> putThread.waitForFirstPut();</span>
<span class="source-line-no">4801</span><span id="line-4801"></span>
<span class="source-line-no">4802</span><span id="line-4802"> // Add a thread that flushes as fast as possible</span>
<span class="source-line-no">4803</span><span id="line-4803"> ctx.addThread(new RepeatingTestThread(ctx) {</span>
<span class="source-line-no">4804</span><span id="line-4804"></span>
<span class="source-line-no">4805</span><span id="line-4805"> @Override</span>
<span class="source-line-no">4806</span><span id="line-4806"> public void doAnAction() throws Exception {</span>
<span class="source-line-no">4807</span><span id="line-4807"> region.flush(true);</span>
<span class="source-line-no">4808</span><span id="line-4808"> // Compact regularly to avoid creating too many files and exceeding</span>
<span class="source-line-no">4809</span><span id="line-4809"> // the ulimit.</span>
<span class="source-line-no">4810</span><span id="line-4810"> region.compact(false);</span>
<span class="source-line-no">4811</span><span id="line-4811"> for (HStore store : region.getStores()) {</span>
<span class="source-line-no">4812</span><span id="line-4812"> store.closeAndArchiveCompactedFiles();</span>
<span class="source-line-no">4813</span><span id="line-4813"> }</span>
<span class="source-line-no">4814</span><span id="line-4814"> }</span>
<span class="source-line-no">4815</span><span id="line-4815"> });</span>
<span class="source-line-no">4816</span><span id="line-4816"> ctx.startThreads();</span>
<span class="source-line-no">4817</span><span id="line-4817"></span>
<span class="source-line-no">4818</span><span id="line-4818"> Get get = new Get(Bytes.toBytes("row0"));</span>
<span class="source-line-no">4819</span><span id="line-4819"> Result result = null;</span>
<span class="source-line-no">4820</span><span id="line-4820"></span>
<span class="source-line-no">4821</span><span id="line-4821"> int expectedCount = numFamilies * numQualifiers;</span>
<span class="source-line-no">4822</span><span id="line-4822"></span>
<span class="source-line-no">4823</span><span id="line-4823"> long prevTimestamp = 0L;</span>
<span class="source-line-no">4824</span><span id="line-4824"> for (int i = 0; i &lt; testCount; i++) {</span>
<span class="source-line-no">4825</span><span id="line-4825"> LOG.info("testWritesWhileGetting verify turn " + i);</span>
<span class="source-line-no">4826</span><span id="line-4826"> boolean previousEmpty = result == null || result.isEmpty();</span>
<span class="source-line-no">4827</span><span id="line-4827"> result = region.get(get);</span>
<span class="source-line-no">4828</span><span id="line-4828"> if (!result.isEmpty() || !previousEmpty || i &gt; compactInterval) {</span>
<span class="source-line-no">4829</span><span id="line-4829"> assertEquals("i=" + i, expectedCount, result.size());</span>
<span class="source-line-no">4830</span><span id="line-4830"> // TODO this was removed, now what dangit?!</span>
<span class="source-line-no">4831</span><span id="line-4831"> // search looking for the qualifier in question?</span>
<span class="source-line-no">4832</span><span id="line-4832"> long timestamp = 0;</span>
<span class="source-line-no">4833</span><span id="line-4833"> for (Cell kv : result.rawCells()) {</span>
<span class="source-line-no">4834</span><span id="line-4834"> if (</span>
<span class="source-line-no">4835</span><span id="line-4835"> CellUtil.matchingFamily(kv, families[0])</span>
<span class="source-line-no">4836</span><span id="line-4836"> &amp;&amp; CellUtil.matchingQualifier(kv, qualifiers[0])</span>
<span class="source-line-no">4837</span><span id="line-4837"> ) {</span>
<span class="source-line-no">4838</span><span id="line-4838"> timestamp = kv.getTimestamp();</span>
<span class="source-line-no">4839</span><span id="line-4839"> }</span>
<span class="source-line-no">4840</span><span id="line-4840"> }</span>
<span class="source-line-no">4841</span><span id="line-4841"> assertTrue(timestamp &gt;= prevTimestamp);</span>
<span class="source-line-no">4842</span><span id="line-4842"> prevTimestamp = timestamp;</span>
<span class="source-line-no">4843</span><span id="line-4843"> ExtendedCell previousKV = null;</span>
<span class="source-line-no">4844</span><span id="line-4844"></span>
<span class="source-line-no">4845</span><span id="line-4845"> for (ExtendedCell kv : ClientInternalHelper.getExtendedRawCells(result)) {</span>
<span class="source-line-no">4846</span><span id="line-4846"> byte[] thisValue = CellUtil.cloneValue(kv);</span>
<span class="source-line-no">4847</span><span id="line-4847"> if (previousKV != null) {</span>
<span class="source-line-no">4848</span><span id="line-4848"> if (Bytes.compareTo(CellUtil.cloneValue(previousKV), thisValue) != 0) {</span>
<span class="source-line-no">4849</span><span id="line-4849"> LOG.warn("These two KV should have the same value." + " Previous KV:" + previousKV</span>
<span class="source-line-no">4850</span><span id="line-4850"> + "(memStoreTS:" + previousKV.getSequenceId() + ")" + ", New KV: " + kv</span>
<span class="source-line-no">4851</span><span id="line-4851"> + "(memStoreTS:" + kv.getSequenceId() + ")");</span>
<span class="source-line-no">4852</span><span id="line-4852"> assertEquals(0, Bytes.compareTo(CellUtil.cloneValue(previousKV), thisValue));</span>
<span class="source-line-no">4853</span><span id="line-4853"> }</span>
<span class="source-line-no">4854</span><span id="line-4854"> }</span>
<span class="source-line-no">4855</span><span id="line-4855"> previousKV = kv;</span>
<span class="source-line-no">4856</span><span id="line-4856"> }</span>
<span class="source-line-no">4857</span><span id="line-4857"> }</span>
<span class="source-line-no">4858</span><span id="line-4858"> }</span>
<span class="source-line-no">4859</span><span id="line-4859"> } finally {</span>
<span class="source-line-no">4860</span><span id="line-4860"> if (putThread != null) putThread.done();</span>
<span class="source-line-no">4861</span><span id="line-4861"></span>
<span class="source-line-no">4862</span><span id="line-4862"> region.flush(true);</span>
<span class="source-line-no">4863</span><span id="line-4863"></span>
<span class="source-line-no">4864</span><span id="line-4864"> if (putThread != null) {</span>
<span class="source-line-no">4865</span><span id="line-4865"> putThread.join();</span>
<span class="source-line-no">4866</span><span id="line-4866"> putThread.checkNoError();</span>
<span class="source-line-no">4867</span><span id="line-4867"> }</span>
<span class="source-line-no">4868</span><span id="line-4868"></span>
<span class="source-line-no">4869</span><span id="line-4869"> ctx.stop();</span>
<span class="source-line-no">4870</span><span id="line-4870"> HBaseTestingUtil.closeRegionAndWAL(this.region);</span>
<span class="source-line-no">4871</span><span id="line-4871"> this.region = null;</span>
<span class="source-line-no">4872</span><span id="line-4872"> }</span>
<span class="source-line-no">4873</span><span id="line-4873"> }</span>
<span class="source-line-no">4874</span><span id="line-4874"></span>
<span class="source-line-no">4875</span><span id="line-4875"> @Test</span>
<span class="source-line-no">4876</span><span id="line-4876"> public void testHolesInMeta() throws Exception {</span>
<span class="source-line-no">4877</span><span id="line-4877"> byte[] family = Bytes.toBytes("family");</span>
<span class="source-line-no">4878</span><span id="line-4878"> this.region =</span>
<span class="source-line-no">4879</span><span id="line-4879"> initHRegion(tableName, Bytes.toBytes("x"), Bytes.toBytes("z"), method, CONF, false, family);</span>
<span class="source-line-no">4880</span><span id="line-4880"> byte[] rowNotServed = Bytes.toBytes("a");</span>
<span class="source-line-no">4881</span><span id="line-4881"> Get g = new Get(rowNotServed);</span>
<span class="source-line-no">4882</span><span id="line-4882"> try {</span>
<span class="source-line-no">4883</span><span id="line-4883"> region.get(g);</span>
<span class="source-line-no">4884</span><span id="line-4884"> fail();</span>
<span class="source-line-no">4885</span><span id="line-4885"> } catch (WrongRegionException x) {</span>
<span class="source-line-no">4886</span><span id="line-4886"> // OK</span>
<span class="source-line-no">4887</span><span id="line-4887"> }</span>
<span class="source-line-no">4888</span><span id="line-4888"> byte[] row = Bytes.toBytes("y");</span>
<span class="source-line-no">4889</span><span id="line-4889"> g = new Get(row);</span>
<span class="source-line-no">4890</span><span id="line-4890"> region.get(g);</span>
<span class="source-line-no">4891</span><span id="line-4891"> }</span>
<span class="source-line-no">4892</span><span id="line-4892"></span>
<span class="source-line-no">4893</span><span id="line-4893"> @Test</span>
<span class="source-line-no">4894</span><span id="line-4894"> public void testIndexesScanWithOneDeletedRow() throws IOException {</span>
<span class="source-line-no">4895</span><span id="line-4895"> byte[] family = Bytes.toBytes("family");</span>
<span class="source-line-no">4896</span><span id="line-4896"></span>
<span class="source-line-no">4897</span><span id="line-4897"> // Setting up region</span>
<span class="source-line-no">4898</span><span id="line-4898"> this.region = initHRegion(tableName, method, CONF, family);</span>
<span class="source-line-no">4899</span><span id="line-4899"> Put put = new Put(Bytes.toBytes(1L));</span>
<span class="source-line-no">4900</span><span id="line-4900"> put.addColumn(family, qual1, 1L, Bytes.toBytes(1L));</span>
<span class="source-line-no">4901</span><span id="line-4901"> region.put(put);</span>
<span class="source-line-no">4902</span><span id="line-4902"></span>
<span class="source-line-no">4903</span><span id="line-4903"> region.flush(true);</span>
<span class="source-line-no">4904</span><span id="line-4904"></span>
<span class="source-line-no">4905</span><span id="line-4905"> Delete delete = new Delete(Bytes.toBytes(1L), 1L);</span>
<span class="source-line-no">4906</span><span id="line-4906"> region.delete(delete);</span>
<span class="source-line-no">4907</span><span id="line-4907"></span>
<span class="source-line-no">4908</span><span id="line-4908"> put = new Put(Bytes.toBytes(2L));</span>
<span class="source-line-no">4909</span><span id="line-4909"> put.addColumn(family, qual1, 2L, Bytes.toBytes(2L));</span>
<span class="source-line-no">4910</span><span id="line-4910"> region.put(put);</span>
<span class="source-line-no">4911</span><span id="line-4911"></span>
<span class="source-line-no">4912</span><span id="line-4912"> Scan idxScan = new Scan();</span>
<span class="source-line-no">4913</span><span id="line-4913"> idxScan.addFamily(family);</span>
<span class="source-line-no">4914</span><span id="line-4914"> idxScan.setFilter(new FilterList(FilterList.Operator.MUST_PASS_ALL,</span>
<span class="source-line-no">4915</span><span id="line-4915"> Arrays.&lt;Filter&gt; asList(</span>
<span class="source-line-no">4916</span><span id="line-4916"> new SingleColumnValueFilter(family, qual1, CompareOperator.GREATER_OR_EQUAL,</span>
<span class="source-line-no">4917</span><span id="line-4917"> new BinaryComparator(Bytes.toBytes(0L))),</span>
<span class="source-line-no">4918</span><span id="line-4918"> new SingleColumnValueFilter(family, qual1, CompareOperator.LESS_OR_EQUAL,</span>
<span class="source-line-no">4919</span><span id="line-4919"> new BinaryComparator(Bytes.toBytes(3L))))));</span>
<span class="source-line-no">4920</span><span id="line-4920"> try (InternalScanner scanner = region.getScanner(idxScan)) {</span>
<span class="source-line-no">4921</span><span id="line-4921"> List&lt;Cell&gt; res = new ArrayList&lt;&gt;();</span>
<span class="source-line-no">4922</span><span id="line-4922"></span>
<span class="source-line-no">4923</span><span id="line-4923"> while (scanner.next(res)) {</span>
<span class="source-line-no">4924</span><span id="line-4924"> // Ignore res value.</span>
<span class="source-line-no">4925</span><span id="line-4925"> }</span>
<span class="source-line-no">4926</span><span id="line-4926"> assertEquals(1L, res.size());</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"></span>
<span class="source-line-no">4930</span><span id="line-4930"> // ////////////////////////////////////////////////////////////////////////////</span>
<span class="source-line-no">4931</span><span id="line-4931"> // Bloom filter test</span>
<span class="source-line-no">4932</span><span id="line-4932"> // ////////////////////////////////////////////////////////////////////////////</span>
<span class="source-line-no">4933</span><span id="line-4933"> @Test</span>
<span class="source-line-no">4934</span><span id="line-4934"> public void testBloomFilterSize() throws IOException {</span>
<span class="source-line-no">4935</span><span id="line-4935"> byte[] fam1 = Bytes.toBytes("fam1");</span>
<span class="source-line-no">4936</span><span id="line-4936"> byte[] qf1 = Bytes.toBytes("col");</span>
<span class="source-line-no">4937</span><span id="line-4937"> byte[] val1 = Bytes.toBytes("value1");</span>
<span class="source-line-no">4938</span><span id="line-4938"> // Create Table</span>
<span class="source-line-no">4939</span><span id="line-4939"> TableDescriptor tableDescriptor = TableDescriptorBuilder.newBuilder(tableName)</span>
<span class="source-line-no">4940</span><span id="line-4940"> .setColumnFamily(ColumnFamilyDescriptorBuilder.newBuilder(fam1)</span>
<span class="source-line-no">4941</span><span id="line-4941"> .setMaxVersions(Integer.MAX_VALUE).setBloomFilterType(BloomType.ROWCOL).build())</span>
<span class="source-line-no">4942</span><span id="line-4942"> .build();</span>
<span class="source-line-no">4943</span><span id="line-4943"> RegionInfo info = RegionInfoBuilder.newBuilder(tableDescriptor.getTableName()).build();</span>
<span class="source-line-no">4944</span><span id="line-4944"> this.region = TEST_UTIL.createLocalHRegion(info, tableDescriptor);</span>
<span class="source-line-no">4945</span><span id="line-4945"> int num_unique_rows = 10;</span>
<span class="source-line-no">4946</span><span id="line-4946"> int duplicate_multiplier = 2;</span>
<span class="source-line-no">4947</span><span id="line-4947"> int num_storefiles = 4;</span>
<span class="source-line-no">4948</span><span id="line-4948"></span>
<span class="source-line-no">4949</span><span id="line-4949"> int version = 0;</span>
<span class="source-line-no">4950</span><span id="line-4950"> for (int f = 0; f &lt; num_storefiles; f++) {</span>
<span class="source-line-no">4951</span><span id="line-4951"> for (int i = 0; i &lt; duplicate_multiplier; i++) {</span>
<span class="source-line-no">4952</span><span id="line-4952"> for (int j = 0; j &lt; num_unique_rows; j++) {</span>
<span class="source-line-no">4953</span><span id="line-4953"> Put put = new Put(Bytes.toBytes("row" + j));</span>
<span class="source-line-no">4954</span><span id="line-4954"> put.setDurability(Durability.SKIP_WAL);</span>
<span class="source-line-no">4955</span><span id="line-4955"> long ts = version++;</span>
<span class="source-line-no">4956</span><span id="line-4956"> put.addColumn(fam1, qf1, ts, val1);</span>
<span class="source-line-no">4957</span><span id="line-4957"> region.put(put);</span>
<span class="source-line-no">4958</span><span id="line-4958"> }</span>
<span class="source-line-no">4959</span><span id="line-4959"> }</span>
<span class="source-line-no">4960</span><span id="line-4960"> region.flush(true);</span>
<span class="source-line-no">4961</span><span id="line-4961"> }</span>
<span class="source-line-no">4962</span><span id="line-4962"> // before compaction</span>
<span class="source-line-no">4963</span><span id="line-4963"> HStore store = region.getStore(fam1);</span>
<span class="source-line-no">4964</span><span id="line-4964"> Collection&lt;HStoreFile&gt; storeFiles = store.getStorefiles();</span>
<span class="source-line-no">4965</span><span id="line-4965"> for (HStoreFile storefile : storeFiles) {</span>
<span class="source-line-no">4966</span><span id="line-4966"> StoreFileReader reader = storefile.getReader();</span>
<span class="source-line-no">4967</span><span id="line-4967"> reader.loadFileInfo();</span>
<span class="source-line-no">4968</span><span id="line-4968"> reader.loadBloomfilter();</span>
<span class="source-line-no">4969</span><span id="line-4969"> assertEquals(num_unique_rows * duplicate_multiplier, reader.getEntries());</span>
<span class="source-line-no">4970</span><span id="line-4970"> assertEquals(num_unique_rows, reader.getFilterEntries());</span>
<span class="source-line-no">4971</span><span id="line-4971"> }</span>
<span class="source-line-no">4972</span><span id="line-4972"></span>
<span class="source-line-no">4973</span><span id="line-4973"> region.compact(true);</span>
<span class="source-line-no">4974</span><span id="line-4974"></span>
<span class="source-line-no">4975</span><span id="line-4975"> // after compaction</span>
<span class="source-line-no">4976</span><span id="line-4976"> storeFiles = store.getStorefiles();</span>
<span class="source-line-no">4977</span><span id="line-4977"> for (HStoreFile storefile : storeFiles) {</span>
<span class="source-line-no">4978</span><span id="line-4978"> StoreFileReader reader = storefile.getReader();</span>
<span class="source-line-no">4979</span><span id="line-4979"> reader.loadFileInfo();</span>
<span class="source-line-no">4980</span><span id="line-4980"> reader.loadBloomfilter();</span>
<span class="source-line-no">4981</span><span id="line-4981"> assertEquals(num_unique_rows * duplicate_multiplier * num_storefiles, reader.getEntries());</span>
<span class="source-line-no">4982</span><span id="line-4982"> assertEquals(num_unique_rows, reader.getFilterEntries());</span>
<span class="source-line-no">4983</span><span id="line-4983"> }</span>
<span class="source-line-no">4984</span><span id="line-4984"> }</span>
<span class="source-line-no">4985</span><span id="line-4985"></span>
<span class="source-line-no">4986</span><span id="line-4986"> @Test</span>
<span class="source-line-no">4987</span><span id="line-4987"> public void testAllColumnsWithBloomFilter() throws IOException {</span>
<span class="source-line-no">4988</span><span id="line-4988"> byte[] TABLE = Bytes.toBytes(name.getMethodName());</span>
<span class="source-line-no">4989</span><span id="line-4989"> byte[] FAMILY = Bytes.toBytes("family");</span>
<span class="source-line-no">4990</span><span id="line-4990"></span>
<span class="source-line-no">4991</span><span id="line-4991"> // Create table</span>
<span class="source-line-no">4992</span><span id="line-4992"> TableDescriptor tableDescriptor = TableDescriptorBuilder.newBuilder(TableName.valueOf(TABLE))</span>
<span class="source-line-no">4993</span><span id="line-4993"> .setColumnFamily(ColumnFamilyDescriptorBuilder.newBuilder(FAMILY)</span>
<span class="source-line-no">4994</span><span id="line-4994"> .setMaxVersions(Integer.MAX_VALUE).setBloomFilterType(BloomType.ROWCOL).build())</span>
<span class="source-line-no">4995</span><span id="line-4995"> .build();</span>
<span class="source-line-no">4996</span><span id="line-4996"> RegionInfo info = RegionInfoBuilder.newBuilder(tableDescriptor.getTableName()).build();</span>
<span class="source-line-no">4997</span><span id="line-4997"> this.region = TEST_UTIL.createLocalHRegion(info, tableDescriptor);</span>
<span class="source-line-no">4998</span><span id="line-4998"> // For row:0, col:0: insert versions 1 through 5.</span>
<span class="source-line-no">4999</span><span id="line-4999"> byte[] row = Bytes.toBytes("row:" + 0);</span>
<span class="source-line-no">5000</span><span id="line-5000"> byte[] column = Bytes.toBytes("column:" + 0);</span>
<span class="source-line-no">5001</span><span id="line-5001"> Put put = new Put(row);</span>
<span class="source-line-no">5002</span><span id="line-5002"> put.setDurability(Durability.SKIP_WAL);</span>
<span class="source-line-no">5003</span><span id="line-5003"> for (long idx = 1; idx &lt;= 4; idx++) {</span>
<span class="source-line-no">5004</span><span id="line-5004"> put.addColumn(FAMILY, column, idx, Bytes.toBytes("value-version-" + idx));</span>
<span class="source-line-no">5005</span><span id="line-5005"> }</span>
<span class="source-line-no">5006</span><span id="line-5006"> region.put(put);</span>
<span class="source-line-no">5007</span><span id="line-5007"></span>
<span class="source-line-no">5008</span><span id="line-5008"> // Flush</span>
<span class="source-line-no">5009</span><span id="line-5009"> region.flush(true);</span>
<span class="source-line-no">5010</span><span id="line-5010"></span>
<span class="source-line-no">5011</span><span id="line-5011"> // Get rows</span>
<span class="source-line-no">5012</span><span id="line-5012"> Get get = new Get(row);</span>
<span class="source-line-no">5013</span><span id="line-5013"> get.readAllVersions();</span>
<span class="source-line-no">5014</span><span id="line-5014"> Cell[] kvs = region.get(get).rawCells();</span>
<span class="source-line-no">5015</span><span id="line-5015"></span>
<span class="source-line-no">5016</span><span id="line-5016"> // Check if rows are correct</span>
<span class="source-line-no">5017</span><span id="line-5017"> assertEquals(4, kvs.length);</span>
<span class="source-line-no">5018</span><span id="line-5018"> checkOneCell(kvs[0], FAMILY, 0, 0, 4);</span>
<span class="source-line-no">5019</span><span id="line-5019"> checkOneCell(kvs[1], FAMILY, 0, 0, 3);</span>
<span class="source-line-no">5020</span><span id="line-5020"> checkOneCell(kvs[2], FAMILY, 0, 0, 2);</span>
<span class="source-line-no">5021</span><span id="line-5021"> checkOneCell(kvs[3], FAMILY, 0, 0, 1);</span>
<span class="source-line-no">5022</span><span id="line-5022"> }</span>
<span class="source-line-no">5023</span><span id="line-5023"></span>
<span class="source-line-no">5024</span><span id="line-5024"> /**</span>
<span class="source-line-no">5025</span><span id="line-5025"> * Testcase to cover bug-fix for HBASE-2823 Ensures correct delete when issuing delete row on</span>
<span class="source-line-no">5026</span><span id="line-5026"> * columns with bloom filter set to row+col (BloomType.ROWCOL)</span>
<span class="source-line-no">5027</span><span id="line-5027"> */</span>
<span class="source-line-no">5028</span><span id="line-5028"> @Test</span>
<span class="source-line-no">5029</span><span id="line-5029"> public void testDeleteRowWithBloomFilter() throws IOException {</span>
<span class="source-line-no">5030</span><span id="line-5030"> byte[] familyName = Bytes.toBytes("familyName");</span>
<span class="source-line-no">5031</span><span id="line-5031"></span>
<span class="source-line-no">5032</span><span id="line-5032"> // Create Table</span>
<span class="source-line-no">5033</span><span id="line-5033"> TableDescriptor tableDescriptor = TableDescriptorBuilder.newBuilder(tableName)</span>
<span class="source-line-no">5034</span><span id="line-5034"> .setColumnFamily(ColumnFamilyDescriptorBuilder.newBuilder(familyName)</span>
<span class="source-line-no">5035</span><span id="line-5035"> .setMaxVersions(Integer.MAX_VALUE).setBloomFilterType(BloomType.ROWCOL).build())</span>
<span class="source-line-no">5036</span><span id="line-5036"> .build();</span>
<span class="source-line-no">5037</span><span id="line-5037"> RegionInfo info = RegionInfoBuilder.newBuilder(tableDescriptor.getTableName()).build();</span>
<span class="source-line-no">5038</span><span id="line-5038"> this.region = TEST_UTIL.createLocalHRegion(info, tableDescriptor);</span>
<span class="source-line-no">5039</span><span id="line-5039"> // Insert some data</span>
<span class="source-line-no">5040</span><span id="line-5040"> byte[] row = Bytes.toBytes("row1");</span>
<span class="source-line-no">5041</span><span id="line-5041"> byte[] col = Bytes.toBytes("col1");</span>
<span class="source-line-no">5042</span><span id="line-5042"></span>
<span class="source-line-no">5043</span><span id="line-5043"> Put put = new Put(row);</span>
<span class="source-line-no">5044</span><span id="line-5044"> put.addColumn(familyName, col, 1, Bytes.toBytes("SomeRandomValue"));</span>
<span class="source-line-no">5045</span><span id="line-5045"> region.put(put);</span>
<span class="source-line-no">5046</span><span id="line-5046"> region.flush(true);</span>
<span class="source-line-no">5047</span><span id="line-5047"></span>
<span class="source-line-no">5048</span><span id="line-5048"> Delete del = new Delete(row);</span>
<span class="source-line-no">5049</span><span id="line-5049"> region.delete(del);</span>
<span class="source-line-no">5050</span><span id="line-5050"> region.flush(true);</span>
<span class="source-line-no">5051</span><span id="line-5051"></span>
<span class="source-line-no">5052</span><span id="line-5052"> // Get remaining rows (should have none)</span>
<span class="source-line-no">5053</span><span id="line-5053"> Get get = new Get(row);</span>
<span class="source-line-no">5054</span><span id="line-5054"> get.addColumn(familyName, col);</span>
<span class="source-line-no">5055</span><span id="line-5055"></span>
<span class="source-line-no">5056</span><span id="line-5056"> Cell[] keyValues = region.get(get).rawCells();</span>
<span class="source-line-no">5057</span><span id="line-5057"> assertEquals(0, keyValues.length);</span>
<span class="source-line-no">5058</span><span id="line-5058"> }</span>
<span class="source-line-no">5059</span><span id="line-5059"></span>
<span class="source-line-no">5060</span><span id="line-5060"> @Test</span>
<span class="source-line-no">5061</span><span id="line-5061"> public void testgetHDFSBlocksDistribution() throws Exception {</span>
<span class="source-line-no">5062</span><span id="line-5062"> HBaseTestingUtil htu = new HBaseTestingUtil();</span>
<span class="source-line-no">5063</span><span id="line-5063"> // 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">5064</span><span id="line-5064"> // break up the file in to more pieces that can be distributed across the three nodes and we</span>
<span class="source-line-no">5065</span><span id="line-5065"> // won't be able to have the condition this test asserts; that at least one node has</span>
<span class="source-line-no">5066</span><span id="line-5066"> // a copy of all replicas -- if small block size, then blocks are spread evenly across the</span>
<span class="source-line-no">5067</span><span id="line-5067"> // the three nodes. hfilev3 with tags seems to put us over the block size. St.Ack.</span>
<span class="source-line-no">5068</span><span id="line-5068"> // final int DEFAULT_BLOCK_SIZE = 1024;</span>
<span class="source-line-no">5069</span><span id="line-5069"> // htu.getConfiguration().setLong("dfs.blocksize", DEFAULT_BLOCK_SIZE);</span>
<span class="source-line-no">5070</span><span id="line-5070"> htu.getConfiguration().setInt("dfs.replication", 2);</span>
<span class="source-line-no">5071</span><span id="line-5071"></span>
<span class="source-line-no">5072</span><span id="line-5072"> // set up a cluster with 3 nodes</span>
<span class="source-line-no">5073</span><span id="line-5073"> SingleProcessHBaseCluster cluster = null;</span>
<span class="source-line-no">5074</span><span id="line-5074"> String dataNodeHosts[] = new String[] { "host1", "host2", "host3" };</span>
<span class="source-line-no">5075</span><span id="line-5075"> int regionServersCount = 3;</span>
<span class="source-line-no">5076</span><span id="line-5076"></span>
<span class="source-line-no">5077</span><span id="line-5077"> try {</span>
<span class="source-line-no">5078</span><span id="line-5078"> StartTestingClusterOption option = StartTestingClusterOption.builder()</span>
<span class="source-line-no">5079</span><span id="line-5079"> .numRegionServers(regionServersCount).dataNodeHosts(dataNodeHosts).build();</span>
<span class="source-line-no">5080</span><span id="line-5080"> cluster = htu.startMiniCluster(option);</span>
<span class="source-line-no">5081</span><span id="line-5081"> byte[][] families = { fam1, fam2 };</span>
<span class="source-line-no">5082</span><span id="line-5082"> Table ht = htu.createTable(tableName, families);</span>
<span class="source-line-no">5083</span><span id="line-5083"></span>
<span class="source-line-no">5084</span><span id="line-5084"> // Setting up region</span>
<span class="source-line-no">5085</span><span id="line-5085"> byte row[] = Bytes.toBytes("row1");</span>
<span class="source-line-no">5086</span><span id="line-5086"> byte col[] = Bytes.toBytes("col1");</span>
<span class="source-line-no">5087</span><span id="line-5087"></span>
<span class="source-line-no">5088</span><span id="line-5088"> Put put = new Put(row);</span>
<span class="source-line-no">5089</span><span id="line-5089"> put.addColumn(fam1, col, 1, Bytes.toBytes("test1"));</span>
<span class="source-line-no">5090</span><span id="line-5090"> put.addColumn(fam2, col, 1, Bytes.toBytes("test2"));</span>
<span class="source-line-no">5091</span><span id="line-5091"> ht.put(put);</span>
<span class="source-line-no">5092</span><span id="line-5092"></span>
<span class="source-line-no">5093</span><span id="line-5093"> HRegion firstRegion = htu.getHBaseCluster().getRegions(tableName).get(0);</span>
<span class="source-line-no">5094</span><span id="line-5094"> firstRegion.flush(true);</span>
<span class="source-line-no">5095</span><span id="line-5095"> HDFSBlocksDistribution blocksDistribution1 = firstRegion.getHDFSBlocksDistribution();</span>
<span class="source-line-no">5096</span><span id="line-5096"></span>
<span class="source-line-no">5097</span><span id="line-5097"> // Given the default replication factor is 2 and we have 2 HFiles,</span>
<span class="source-line-no">5098</span><span id="line-5098"> // we will have total of 4 replica of blocks on 3 datanodes; thus there</span>
<span class="source-line-no">5099</span><span id="line-5099"> // must be at least one host that have replica for 2 HFiles. That host's</span>
<span class="source-line-no">5100</span><span id="line-5100"> // weight will be equal to the unique block weight.</span>
<span class="source-line-no">5101</span><span id="line-5101"> long uniqueBlocksWeight1 = blocksDistribution1.getUniqueBlocksTotalWeight();</span>
<span class="source-line-no">5102</span><span id="line-5102"> StringBuilder sb = new StringBuilder();</span>
<span class="source-line-no">5103</span><span id="line-5103"> for (String host : blocksDistribution1.getTopHosts()) {</span>
<span class="source-line-no">5104</span><span id="line-5104"> if (sb.length() &gt; 0) sb.append(", ");</span>
<span class="source-line-no">5105</span><span id="line-5105"> sb.append(host);</span>
<span class="source-line-no">5106</span><span id="line-5106"> sb.append("=");</span>
<span class="source-line-no">5107</span><span id="line-5107"> sb.append(blocksDistribution1.getWeight(host));</span>
<span class="source-line-no">5108</span><span id="line-5108"> }</span>
<span class="source-line-no">5109</span><span id="line-5109"></span>
<span class="source-line-no">5110</span><span id="line-5110"> String topHost = blocksDistribution1.getTopHosts().get(0);</span>
<span class="source-line-no">5111</span><span id="line-5111"> long topHostWeight = blocksDistribution1.getWeight(topHost);</span>
<span class="source-line-no">5112</span><span id="line-5112"> String msg = "uniqueBlocksWeight=" + uniqueBlocksWeight1 + ", topHostWeight=" + topHostWeight</span>
<span class="source-line-no">5113</span><span id="line-5113"> + ", topHost=" + topHost + "; " + sb.toString();</span>
<span class="source-line-no">5114</span><span id="line-5114"> LOG.info(msg);</span>
<span class="source-line-no">5115</span><span id="line-5115"> assertTrue(msg, uniqueBlocksWeight1 == topHostWeight);</span>
<span class="source-line-no">5116</span><span id="line-5116"></span>
<span class="source-line-no">5117</span><span id="line-5117"> // use the static method to compute the value, it should be the same.</span>
<span class="source-line-no">5118</span><span id="line-5118"> // static method is used by load balancer or other components</span>
<span class="source-line-no">5119</span><span id="line-5119"> HDFSBlocksDistribution blocksDistribution2 = HRegion.computeHDFSBlocksDistribution(</span>
<span class="source-line-no">5120</span><span id="line-5120"> htu.getConfiguration(), firstRegion.getTableDescriptor(), firstRegion.getRegionInfo());</span>
<span class="source-line-no">5121</span><span id="line-5121"> long uniqueBlocksWeight2 = blocksDistribution2.getUniqueBlocksTotalWeight();</span>
<span class="source-line-no">5122</span><span id="line-5122"></span>
<span class="source-line-no">5123</span><span id="line-5123"> assertTrue(uniqueBlocksWeight1 == uniqueBlocksWeight2);</span>
<span class="source-line-no">5124</span><span id="line-5124"></span>
<span class="source-line-no">5125</span><span id="line-5125"> ht.close();</span>
<span class="source-line-no">5126</span><span id="line-5126"> } finally {</span>
<span class="source-line-no">5127</span><span id="line-5127"> if (cluster != null) {</span>
<span class="source-line-no">5128</span><span id="line-5128"> htu.shutdownMiniCluster();</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"></span>
<span class="source-line-no">5133</span><span id="line-5133"> /**</span>
<span class="source-line-no">5134</span><span id="line-5134"> * Testcase to check state of region initialization task set to ABORTED or not if any exceptions</span>
<span class="source-line-no">5135</span><span id="line-5135"> * during initialization</span>
<span class="source-line-no">5136</span><span id="line-5136"> */</span>
<span class="source-line-no">5137</span><span id="line-5137"> @Test</span>
<span class="source-line-no">5138</span><span id="line-5138"> public void testStatusSettingToAbortIfAnyExceptionDuringRegionInitilization() throws Exception {</span>
<span class="source-line-no">5139</span><span id="line-5139"> RegionInfo info;</span>
<span class="source-line-no">5140</span><span id="line-5140"> try {</span>
<span class="source-line-no">5141</span><span id="line-5141"> FileSystem fs = mock(FileSystem.class);</span>
<span class="source-line-no">5142</span><span id="line-5142"> when(fs.exists(any())).thenThrow(new IOException());</span>
<span class="source-line-no">5143</span><span id="line-5143"> TableDescriptorBuilder tableDescriptorBuilder = TableDescriptorBuilder.newBuilder(tableName);</span>
<span class="source-line-no">5144</span><span id="line-5144"> ColumnFamilyDescriptor columnFamilyDescriptor =</span>
<span class="source-line-no">5145</span><span id="line-5145"> ColumnFamilyDescriptorBuilder.newBuilder(Bytes.toBytes("cf")).build();</span>
<span class="source-line-no">5146</span><span id="line-5146"> tableDescriptorBuilder.setColumnFamily(columnFamilyDescriptor);</span>
<span class="source-line-no">5147</span><span id="line-5147"> info = RegionInfoBuilder.newBuilder(tableName).build();</span>
<span class="source-line-no">5148</span><span id="line-5148"> Path path = new Path(dir + "testStatusSettingToAbortIfAnyExceptionDuringRegionInitilization");</span>
<span class="source-line-no">5149</span><span id="line-5149"> region = HRegion.newHRegion(path, null, fs, CONF, info, tableDescriptorBuilder.build(), null);</span>
<span class="source-line-no">5150</span><span id="line-5150"> // region initialization throws IOException and set task state to ABORTED.</span>
<span class="source-line-no">5151</span><span id="line-5151"> region.initialize();</span>
<span class="source-line-no">5152</span><span id="line-5152"> fail("Region initialization should fail due to IOException");</span>
<span class="source-line-no">5153</span><span id="line-5153"> } catch (IOException io) {</span>
<span class="source-line-no">5154</span><span id="line-5154"> List&lt;MonitoredTask&gt; tasks = TaskMonitor.get().getTasks();</span>
<span class="source-line-no">5155</span><span id="line-5155"> for (MonitoredTask monitoredTask : tasks) {</span>
<span class="source-line-no">5156</span><span id="line-5156"> if (</span>
<span class="source-line-no">5157</span><span id="line-5157"> !(monitoredTask instanceof MonitoredRPCHandler)</span>
<span class="source-line-no">5158</span><span id="line-5158"> &amp;&amp; monitoredTask.getDescription().contains(region.toString())</span>
<span class="source-line-no">5159</span><span id="line-5159"> ) {</span>
<span class="source-line-no">5160</span><span id="line-5160"> assertTrue("Region state should be ABORTED.",</span>
<span class="source-line-no">5161</span><span id="line-5161"> monitoredTask.getState().equals(MonitoredTask.State.ABORTED));</span>
<span class="source-line-no">5162</span><span id="line-5162"> break;</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"></span>
<span class="source-line-no">5168</span><span id="line-5168"> /**</span>
<span class="source-line-no">5169</span><span id="line-5169"> * Verifies that the .regioninfo file is written on region creation and that is recreated if</span>
<span class="source-line-no">5170</span><span id="line-5170"> * missing during region opening.</span>
<span class="source-line-no">5171</span><span id="line-5171"> */</span>
<span class="source-line-no">5172</span><span id="line-5172"> @Test</span>
<span class="source-line-no">5173</span><span id="line-5173"> public void testRegionInfoFileCreation() throws IOException {</span>
<span class="source-line-no">5174</span><span id="line-5174"> Path rootDir = new Path(dir + "testRegionInfoFileCreation");</span>
<span class="source-line-no">5175</span><span id="line-5175"></span>
<span class="source-line-no">5176</span><span id="line-5176"> TableDescriptorBuilder tableDescriptorBuilder =</span>
<span class="source-line-no">5177</span><span id="line-5177"> TableDescriptorBuilder.newBuilder(TableName.valueOf(name.getMethodName()));</span>
<span class="source-line-no">5178</span><span id="line-5178"> ColumnFamilyDescriptor columnFamilyDescriptor =</span>
<span class="source-line-no">5179</span><span id="line-5179"> ColumnFamilyDescriptorBuilder.newBuilder(Bytes.toBytes("cf")).build();</span>
<span class="source-line-no">5180</span><span id="line-5180"> tableDescriptorBuilder.setColumnFamily(columnFamilyDescriptor);</span>
<span class="source-line-no">5181</span><span id="line-5181"> TableDescriptor tableDescriptor = tableDescriptorBuilder.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"> RegionInfo hri = RegionInfoBuilder.newBuilder(tableDescriptor.getTableName()).build();</span>
<span class="source-line-no">5184</span><span id="line-5184"></span>
<span class="source-line-no">5185</span><span id="line-5185"> // Create a region and skip the initialization (like CreateTableHandler)</span>
<span class="source-line-no">5186</span><span id="line-5186"> region = HBaseTestingUtil.createRegionAndWAL(hri, rootDir, CONF, tableDescriptor, false);</span>
<span class="source-line-no">5187</span><span id="line-5187"> Path regionDir = region.getRegionFileSystem().getRegionDir();</span>
<span class="source-line-no">5188</span><span id="line-5188"> FileSystem fs = region.getRegionFileSystem().getFileSystem();</span>
<span class="source-line-no">5189</span><span id="line-5189"> HBaseTestingUtil.closeRegionAndWAL(region);</span>
<span class="source-line-no">5190</span><span id="line-5190"></span>
<span class="source-line-no">5191</span><span id="line-5191"> Path regionInfoFile = new Path(regionDir, HRegionFileSystem.REGION_INFO_FILE);</span>
<span class="source-line-no">5192</span><span id="line-5192"></span>
<span class="source-line-no">5193</span><span id="line-5193"> // Verify that the .regioninfo file is present</span>
<span class="source-line-no">5194</span><span id="line-5194"> assertTrue(HRegionFileSystem.REGION_INFO_FILE + " should be present in the region dir",</span>
<span class="source-line-no">5195</span><span id="line-5195"> fs.exists(regionInfoFile));</span>
<span class="source-line-no">5196</span><span id="line-5196"></span>
<span class="source-line-no">5197</span><span id="line-5197"> // Try to open the region</span>
<span class="source-line-no">5198</span><span id="line-5198"> region = HRegion.openHRegion(rootDir, hri, tableDescriptor, null, CONF);</span>
<span class="source-line-no">5199</span><span id="line-5199"> assertEquals(regionDir, region.getRegionFileSystem().getRegionDir());</span>
<span class="source-line-no">5200</span><span id="line-5200"> HBaseTestingUtil.closeRegionAndWAL(region);</span>
<span class="source-line-no">5201</span><span id="line-5201"></span>
<span class="source-line-no">5202</span><span id="line-5202"> // Verify that the .regioninfo file is still there</span>
<span class="source-line-no">5203</span><span id="line-5203"> assertTrue(HRegionFileSystem.REGION_INFO_FILE + " should be present in the region dir",</span>
<span class="source-line-no">5204</span><span id="line-5204"> fs.exists(regionInfoFile));</span>
<span class="source-line-no">5205</span><span id="line-5205"></span>
<span class="source-line-no">5206</span><span id="line-5206"> // Remove the .regioninfo file and verify is recreated on region open</span>
<span class="source-line-no">5207</span><span id="line-5207"> fs.delete(regionInfoFile, true);</span>
<span class="source-line-no">5208</span><span id="line-5208"> assertFalse(HRegionFileSystem.REGION_INFO_FILE + " should be removed from the region dir",</span>
<span class="source-line-no">5209</span><span id="line-5209"> fs.exists(regionInfoFile));</span>
<span class="source-line-no">5210</span><span id="line-5210"></span>
<span class="source-line-no">5211</span><span id="line-5211"> region = HRegion.openHRegion(rootDir, hri, tableDescriptor, null, CONF);</span>
<span class="source-line-no">5212</span><span id="line-5212"> // region = TEST_UTIL.openHRegion(hri, htd);</span>
<span class="source-line-no">5213</span><span id="line-5213"> assertEquals(regionDir, region.getRegionFileSystem().getRegionDir());</span>
<span class="source-line-no">5214</span><span id="line-5214"> HBaseTestingUtil.closeRegionAndWAL(region);</span>
<span class="source-line-no">5215</span><span id="line-5215"></span>
<span class="source-line-no">5216</span><span id="line-5216"> // Verify that the .regioninfo file is still there</span>
<span class="source-line-no">5217</span><span id="line-5217"> assertTrue(HRegionFileSystem.REGION_INFO_FILE + " should be present in the region dir",</span>
<span class="source-line-no">5218</span><span id="line-5218"> fs.exists(new Path(regionDir, HRegionFileSystem.REGION_INFO_FILE)));</span>
<span class="source-line-no">5219</span><span id="line-5219"></span>
<span class="source-line-no">5220</span><span id="line-5220"> region = null;</span>
<span class="source-line-no">5221</span><span id="line-5221"> }</span>
<span class="source-line-no">5222</span><span id="line-5222"></span>
<span class="source-line-no">5223</span><span id="line-5223"> /**</span>
<span class="source-line-no">5224</span><span id="line-5224"> * TestCase for increment</span>
<span class="source-line-no">5225</span><span id="line-5225"> */</span>
<span class="source-line-no">5226</span><span id="line-5226"> private static class Incrementer implements Runnable {</span>
<span class="source-line-no">5227</span><span id="line-5227"> private HRegion region;</span>
<span class="source-line-no">5228</span><span id="line-5228"> private final static byte[] incRow = Bytes.toBytes("incRow");</span>
<span class="source-line-no">5229</span><span id="line-5229"> private final static byte[] family = Bytes.toBytes("family");</span>
<span class="source-line-no">5230</span><span id="line-5230"> private final static byte[] qualifier = Bytes.toBytes("qualifier");</span>
<span class="source-line-no">5231</span><span id="line-5231"> private final static long ONE = 1L;</span>
<span class="source-line-no">5232</span><span id="line-5232"> private int incCounter;</span>
<span class="source-line-no">5233</span><span id="line-5233"></span>
<span class="source-line-no">5234</span><span id="line-5234"> public Incrementer(HRegion region, int incCounter) {</span>
<span class="source-line-no">5235</span><span id="line-5235"> this.region = region;</span>
<span class="source-line-no">5236</span><span id="line-5236"> this.incCounter = incCounter;</span>
<span class="source-line-no">5237</span><span id="line-5237"> }</span>
<span class="source-line-no">5238</span><span id="line-5238"></span>
<span class="source-line-no">5239</span><span id="line-5239"> @Override</span>
<span class="source-line-no">5240</span><span id="line-5240"> public void run() {</span>
<span class="source-line-no">5241</span><span id="line-5241"> int count = 0;</span>
<span class="source-line-no">5242</span><span id="line-5242"> while (count &lt; incCounter) {</span>
<span class="source-line-no">5243</span><span id="line-5243"> Increment inc = new Increment(incRow);</span>
<span class="source-line-no">5244</span><span id="line-5244"> inc.addColumn(family, qualifier, ONE);</span>
<span class="source-line-no">5245</span><span id="line-5245"> count++;</span>
<span class="source-line-no">5246</span><span id="line-5246"> try {</span>
<span class="source-line-no">5247</span><span id="line-5247"> region.increment(inc);</span>
<span class="source-line-no">5248</span><span id="line-5248"> } catch (IOException e) {</span>
<span class="source-line-no">5249</span><span id="line-5249"> LOG.info("Count=" + count + ", " + e);</span>
<span class="source-line-no">5250</span><span id="line-5250"> break;</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"></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 case to check increment function with memstore flushing</span>
<span class="source-line-no">5258</span><span id="line-5258"> */</span>
<span class="source-line-no">5259</span><span id="line-5259"> @Test</span>
<span class="source-line-no">5260</span><span id="line-5260"> public void testParallelIncrementWithMemStoreFlush() throws Exception {</span>
<span class="source-line-no">5261</span><span id="line-5261"> byte[] family = Incrementer.family;</span>
<span class="source-line-no">5262</span><span id="line-5262"> this.region = initHRegion(tableName, method, CONF, family);</span>
<span class="source-line-no">5263</span><span id="line-5263"> final HRegion region = this.region;</span>
<span class="source-line-no">5264</span><span id="line-5264"> final AtomicBoolean incrementDone = new AtomicBoolean(false);</span>
<span class="source-line-no">5265</span><span id="line-5265"> Runnable flusher = new Runnable() {</span>
<span class="source-line-no">5266</span><span id="line-5266"> @Override</span>
<span class="source-line-no">5267</span><span id="line-5267"> public void run() {</span>
<span class="source-line-no">5268</span><span id="line-5268"> while (!incrementDone.get()) {</span>
<span class="source-line-no">5269</span><span id="line-5269"> try {</span>
<span class="source-line-no">5270</span><span id="line-5270"> region.flush(true);</span>
<span class="source-line-no">5271</span><span id="line-5271"> } catch (Exception e) {</span>
<span class="source-line-no">5272</span><span id="line-5272"> e.printStackTrace();</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"> };</span>
<span class="source-line-no">5277</span><span id="line-5277"></span>
<span class="source-line-no">5278</span><span id="line-5278"> // after all increment finished, the row will increment to 20*100 = 2000</span>
<span class="source-line-no">5279</span><span id="line-5279"> int threadNum = 20;</span>
<span class="source-line-no">5280</span><span id="line-5280"> int incCounter = 100;</span>
<span class="source-line-no">5281</span><span id="line-5281"> long expected = (long) threadNum * incCounter;</span>
<span class="source-line-no">5282</span><span id="line-5282"> Thread[] incrementers = new Thread[threadNum];</span>
<span class="source-line-no">5283</span><span id="line-5283"> Thread flushThread = new Thread(flusher);</span>
<span class="source-line-no">5284</span><span id="line-5284"> for (int i = 0; i &lt; threadNum; i++) {</span>
<span class="source-line-no">5285</span><span id="line-5285"> incrementers[i] = new Thread(new Incrementer(this.region, incCounter));</span>
<span class="source-line-no">5286</span><span id="line-5286"> incrementers[i].start();</span>
<span class="source-line-no">5287</span><span id="line-5287"> }</span>
<span class="source-line-no">5288</span><span id="line-5288"> flushThread.start();</span>
<span class="source-line-no">5289</span><span id="line-5289"> for (int i = 0; i &lt; threadNum; i++) {</span>
<span class="source-line-no">5290</span><span id="line-5290"> incrementers[i].join();</span>
<span class="source-line-no">5291</span><span id="line-5291"> }</span>
<span class="source-line-no">5292</span><span id="line-5292"></span>
<span class="source-line-no">5293</span><span id="line-5293"> incrementDone.set(true);</span>
<span class="source-line-no">5294</span><span id="line-5294"> flushThread.join();</span>
<span class="source-line-no">5295</span><span id="line-5295"></span>
<span class="source-line-no">5296</span><span id="line-5296"> Get get = new Get(Incrementer.incRow);</span>
<span class="source-line-no">5297</span><span id="line-5297"> get.addColumn(Incrementer.family, Incrementer.qualifier);</span>
<span class="source-line-no">5298</span><span id="line-5298"> get.readVersions(1);</span>
<span class="source-line-no">5299</span><span id="line-5299"> Result res = this.region.get(get);</span>
<span class="source-line-no">5300</span><span id="line-5300"> List&lt;Cell&gt; kvs = res.getColumnCells(Incrementer.family, Incrementer.qualifier);</span>
<span class="source-line-no">5301</span><span id="line-5301"></span>
<span class="source-line-no">5302</span><span id="line-5302"> // we just got the latest version</span>
<span class="source-line-no">5303</span><span id="line-5303"> assertEquals(1, kvs.size());</span>
<span class="source-line-no">5304</span><span id="line-5304"> Cell kv = kvs.get(0);</span>
<span class="source-line-no">5305</span><span id="line-5305"> assertEquals(expected, Bytes.toLong(kv.getValueArray(), kv.getValueOffset()));</span>
<span class="source-line-no">5306</span><span id="line-5306"> }</span>
<span class="source-line-no">5307</span><span id="line-5307"></span>
<span class="source-line-no">5308</span><span id="line-5308"> /**</span>
<span class="source-line-no">5309</span><span id="line-5309"> * TestCase for append</span>
<span class="source-line-no">5310</span><span id="line-5310"> */</span>
<span class="source-line-no">5311</span><span id="line-5311"> private static class Appender implements Runnable {</span>
<span class="source-line-no">5312</span><span id="line-5312"> private HRegion region;</span>
<span class="source-line-no">5313</span><span id="line-5313"> private final static byte[] appendRow = Bytes.toBytes("appendRow");</span>
<span class="source-line-no">5314</span><span id="line-5314"> private final static byte[] family = Bytes.toBytes("family");</span>
<span class="source-line-no">5315</span><span id="line-5315"> private final static byte[] qualifier = Bytes.toBytes("qualifier");</span>
<span class="source-line-no">5316</span><span id="line-5316"> private final static byte[] CHAR = Bytes.toBytes("a");</span>
<span class="source-line-no">5317</span><span id="line-5317"> private int appendCounter;</span>
<span class="source-line-no">5318</span><span id="line-5318"></span>
<span class="source-line-no">5319</span><span id="line-5319"> public Appender(HRegion region, int appendCounter) {</span>
<span class="source-line-no">5320</span><span id="line-5320"> this.region = region;</span>
<span class="source-line-no">5321</span><span id="line-5321"> this.appendCounter = appendCounter;</span>
<span class="source-line-no">5322</span><span id="line-5322"> }</span>
<span class="source-line-no">5323</span><span id="line-5323"></span>
<span class="source-line-no">5324</span><span id="line-5324"> @Override</span>
<span class="source-line-no">5325</span><span id="line-5325"> public void run() {</span>
<span class="source-line-no">5326</span><span id="line-5326"> int count = 0;</span>
<span class="source-line-no">5327</span><span id="line-5327"> while (count &lt; appendCounter) {</span>
<span class="source-line-no">5328</span><span id="line-5328"> Append app = new Append(appendRow);</span>
<span class="source-line-no">5329</span><span id="line-5329"> app.addColumn(family, qualifier, CHAR);</span>
<span class="source-line-no">5330</span><span id="line-5330"> count++;</span>
<span class="source-line-no">5331</span><span id="line-5331"> try {</span>
<span class="source-line-no">5332</span><span id="line-5332"> region.append(app);</span>
<span class="source-line-no">5333</span><span id="line-5333"> } catch (IOException e) {</span>
<span class="source-line-no">5334</span><span id="line-5334"> LOG.info("Count=" + count + ", max=" + appendCounter + ", " + e);</span>
<span class="source-line-no">5335</span><span id="line-5335"> break;</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"></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 case to check append function with memstore flushing</span>
<span class="source-line-no">5343</span><span id="line-5343"> */</span>
<span class="source-line-no">5344</span><span id="line-5344"> @Test</span>
<span class="source-line-no">5345</span><span id="line-5345"> public void testParallelAppendWithMemStoreFlush() throws Exception {</span>
<span class="source-line-no">5346</span><span id="line-5346"> byte[] family = Appender.family;</span>
<span class="source-line-no">5347</span><span id="line-5347"> this.region = initHRegion(tableName, method, CONF, family);</span>
<span class="source-line-no">5348</span><span id="line-5348"> final HRegion region = this.region;</span>
<span class="source-line-no">5349</span><span id="line-5349"> final AtomicBoolean appendDone = new AtomicBoolean(false);</span>
<span class="source-line-no">5350</span><span id="line-5350"> Runnable flusher = new Runnable() {</span>
<span class="source-line-no">5351</span><span id="line-5351"> @Override</span>
<span class="source-line-no">5352</span><span id="line-5352"> public void run() {</span>
<span class="source-line-no">5353</span><span id="line-5353"> while (!appendDone.get()) {</span>
<span class="source-line-no">5354</span><span id="line-5354"> try {</span>
<span class="source-line-no">5355</span><span id="line-5355"> region.flush(true);</span>
<span class="source-line-no">5356</span><span id="line-5356"> } catch (Exception e) {</span>
<span class="source-line-no">5357</span><span id="line-5357"> e.printStackTrace();</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"> };</span>
<span class="source-line-no">5362</span><span id="line-5362"></span>
<span class="source-line-no">5363</span><span id="line-5363"> // After all append finished, the value will append to threadNum *</span>
<span class="source-line-no">5364</span><span id="line-5364"> // appendCounter Appender.CHAR</span>
<span class="source-line-no">5365</span><span id="line-5365"> int threadNum = 20;</span>
<span class="source-line-no">5366</span><span id="line-5366"> int appendCounter = 100;</span>
<span class="source-line-no">5367</span><span id="line-5367"> byte[] expected = new byte[threadNum * appendCounter];</span>
<span class="source-line-no">5368</span><span id="line-5368"> for (int i = 0; i &lt; threadNum * appendCounter; i++) {</span>
<span class="source-line-no">5369</span><span id="line-5369"> System.arraycopy(Appender.CHAR, 0, expected, i, 1);</span>
<span class="source-line-no">5370</span><span id="line-5370"> }</span>
<span class="source-line-no">5371</span><span id="line-5371"> Thread[] appenders = new Thread[threadNum];</span>
<span class="source-line-no">5372</span><span id="line-5372"> Thread flushThread = new Thread(flusher);</span>
<span class="source-line-no">5373</span><span id="line-5373"> for (int i = 0; i &lt; threadNum; i++) {</span>
<span class="source-line-no">5374</span><span id="line-5374"> appenders[i] = new Thread(new Appender(this.region, appendCounter));</span>
<span class="source-line-no">5375</span><span id="line-5375"> appenders[i].start();</span>
<span class="source-line-no">5376</span><span id="line-5376"> }</span>
<span class="source-line-no">5377</span><span id="line-5377"> flushThread.start();</span>
<span class="source-line-no">5378</span><span id="line-5378"> for (int i = 0; i &lt; threadNum; i++) {</span>
<span class="source-line-no">5379</span><span id="line-5379"> appenders[i].join();</span>
<span class="source-line-no">5380</span><span id="line-5380"> }</span>
<span class="source-line-no">5381</span><span id="line-5381"></span>
<span class="source-line-no">5382</span><span id="line-5382"> appendDone.set(true);</span>
<span class="source-line-no">5383</span><span id="line-5383"> flushThread.join();</span>
<span class="source-line-no">5384</span><span id="line-5384"></span>
<span class="source-line-no">5385</span><span id="line-5385"> Get get = new Get(Appender.appendRow);</span>
<span class="source-line-no">5386</span><span id="line-5386"> get.addColumn(Appender.family, Appender.qualifier);</span>
<span class="source-line-no">5387</span><span id="line-5387"> get.readVersions(1);</span>
<span class="source-line-no">5388</span><span id="line-5388"> Result res = this.region.get(get);</span>
<span class="source-line-no">5389</span><span id="line-5389"> List&lt;Cell&gt; kvs = res.getColumnCells(Appender.family, Appender.qualifier);</span>
<span class="source-line-no">5390</span><span id="line-5390"></span>
<span class="source-line-no">5391</span><span id="line-5391"> // we just got the latest version</span>
<span class="source-line-no">5392</span><span id="line-5392"> assertEquals(1, kvs.size());</span>
<span class="source-line-no">5393</span><span id="line-5393"> Cell kv = kvs.get(0);</span>
<span class="source-line-no">5394</span><span id="line-5394"> byte[] appendResult = new byte[kv.getValueLength()];</span>
<span class="source-line-no">5395</span><span id="line-5395"> System.arraycopy(kv.getValueArray(), kv.getValueOffset(), appendResult, 0, kv.getValueLength());</span>
<span class="source-line-no">5396</span><span id="line-5396"> assertArrayEquals(expected, appendResult);</span>
<span class="source-line-no">5397</span><span id="line-5397"> }</span>
<span class="source-line-no">5398</span><span id="line-5398"></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 case to check put function with memstore flushing for same row, same ts</span>
<span class="source-line-no">5401</span><span id="line-5401"> */</span>
<span class="source-line-no">5402</span><span id="line-5402"> @Test</span>
<span class="source-line-no">5403</span><span id="line-5403"> public void testPutWithMemStoreFlush() throws Exception {</span>
<span class="source-line-no">5404</span><span id="line-5404"> byte[] family = Bytes.toBytes("family");</span>
<span class="source-line-no">5405</span><span id="line-5405"> byte[] qualifier = Bytes.toBytes("qualifier");</span>
<span class="source-line-no">5406</span><span id="line-5406"> byte[] row = Bytes.toBytes("putRow");</span>
<span class="source-line-no">5407</span><span id="line-5407"> byte[] value = null;</span>
<span class="source-line-no">5408</span><span id="line-5408"> this.region = initHRegion(tableName, method, CONF, family);</span>
<span class="source-line-no">5409</span><span id="line-5409"> Put put = null;</span>
<span class="source-line-no">5410</span><span id="line-5410"> Get get = null;</span>
<span class="source-line-no">5411</span><span id="line-5411"> List&lt;Cell&gt; kvs = null;</span>
<span class="source-line-no">5412</span><span id="line-5412"> Result res = null;</span>
<span class="source-line-no">5413</span><span id="line-5413"></span>
<span class="source-line-no">5414</span><span id="line-5414"> put = new Put(row);</span>
<span class="source-line-no">5415</span><span id="line-5415"> value = Bytes.toBytes("value0");</span>
<span class="source-line-no">5416</span><span id="line-5416"> put.addColumn(family, qualifier, 1234567L, value);</span>
<span class="source-line-no">5417</span><span id="line-5417"> region.put(put);</span>
<span class="source-line-no">5418</span><span id="line-5418"> get = new Get(row);</span>
<span class="source-line-no">5419</span><span id="line-5419"> get.addColumn(family, qualifier);</span>
<span class="source-line-no">5420</span><span id="line-5420"> get.readAllVersions();</span>
<span class="source-line-no">5421</span><span id="line-5421"> res = this.region.get(get);</span>
<span class="source-line-no">5422</span><span id="line-5422"> kvs = res.getColumnCells(family, qualifier);</span>
<span class="source-line-no">5423</span><span id="line-5423"> assertEquals(1, kvs.size());</span>
<span class="source-line-no">5424</span><span id="line-5424"> assertArrayEquals(Bytes.toBytes("value0"), CellUtil.cloneValue(kvs.get(0)));</span>
<span class="source-line-no">5425</span><span id="line-5425"></span>
<span class="source-line-no">5426</span><span id="line-5426"> region.flush(true);</span>
<span class="source-line-no">5427</span><span id="line-5427"> get = new Get(row);</span>
<span class="source-line-no">5428</span><span id="line-5428"> get.addColumn(family, qualifier);</span>
<span class="source-line-no">5429</span><span id="line-5429"> get.readAllVersions();</span>
<span class="source-line-no">5430</span><span id="line-5430"> res = this.region.get(get);</span>
<span class="source-line-no">5431</span><span id="line-5431"> kvs = res.getColumnCells(family, qualifier);</span>
<span class="source-line-no">5432</span><span id="line-5432"> assertEquals(1, kvs.size());</span>
<span class="source-line-no">5433</span><span id="line-5433"> assertArrayEquals(Bytes.toBytes("value0"), CellUtil.cloneValue(kvs.get(0)));</span>
<span class="source-line-no">5434</span><span id="line-5434"></span>
<span class="source-line-no">5435</span><span id="line-5435"> put = new Put(row);</span>
<span class="source-line-no">5436</span><span id="line-5436"> value = Bytes.toBytes("value1");</span>
<span class="source-line-no">5437</span><span id="line-5437"> put.addColumn(family, qualifier, 1234567L, value);</span>
<span class="source-line-no">5438</span><span id="line-5438"> region.put(put);</span>
<span class="source-line-no">5439</span><span id="line-5439"> get = new Get(row);</span>
<span class="source-line-no">5440</span><span id="line-5440"> get.addColumn(family, qualifier);</span>
<span class="source-line-no">5441</span><span id="line-5441"> get.readAllVersions();</span>
<span class="source-line-no">5442</span><span id="line-5442"> res = this.region.get(get);</span>
<span class="source-line-no">5443</span><span id="line-5443"> kvs = res.getColumnCells(family, qualifier);</span>
<span class="source-line-no">5444</span><span id="line-5444"> assertEquals(1, kvs.size());</span>
<span class="source-line-no">5445</span><span id="line-5445"> assertArrayEquals(Bytes.toBytes("value1"), CellUtil.cloneValue(kvs.get(0)));</span>
<span class="source-line-no">5446</span><span id="line-5446"></span>
<span class="source-line-no">5447</span><span id="line-5447"> region.flush(true);</span>
<span class="source-line-no">5448</span><span id="line-5448"> get = new Get(row);</span>
<span class="source-line-no">5449</span><span id="line-5449"> get.addColumn(family, qualifier);</span>
<span class="source-line-no">5450</span><span id="line-5450"> get.readAllVersions();</span>
<span class="source-line-no">5451</span><span id="line-5451"> res = this.region.get(get);</span>
<span class="source-line-no">5452</span><span id="line-5452"> kvs = res.getColumnCells(family, qualifier);</span>
<span class="source-line-no">5453</span><span id="line-5453"> assertEquals(1, kvs.size());</span>
<span class="source-line-no">5454</span><span id="line-5454"> assertArrayEquals(Bytes.toBytes("value1"), CellUtil.cloneValue(kvs.get(0)));</span>
<span class="source-line-no">5455</span><span id="line-5455"> }</span>
<span class="source-line-no">5456</span><span id="line-5456"></span>
<span class="source-line-no">5457</span><span id="line-5457"> /**</span>
<span class="source-line-no">5458</span><span id="line-5458"> * For this test,the spied {@link AsyncFSWAL} can not work properly because of a Mockito defect</span>
<span class="source-line-no">5459</span><span id="line-5459"> * that can not deal with classes which have a field of an inner class. See discussions in</span>
<span class="source-line-no">5460</span><span id="line-5460"> * HBASE-15536.When we reuse the code of {@link AsyncFSWAL} for {@link FSHLog}, this test could</span>
<span class="source-line-no">5461</span><span id="line-5461"> * not work for {@link FSHLog} also.</span>
<span class="source-line-no">5462</span><span id="line-5462"> */</span>
<span class="source-line-no">5463</span><span id="line-5463"> @Test</span>
<span class="source-line-no">5464</span><span id="line-5464"> @Ignore</span>
<span class="source-line-no">5465</span><span id="line-5465"> public void testDurability() throws Exception {</span>
<span class="source-line-no">5466</span><span id="line-5466"> // there are 5 x 5 cases:</span>
<span class="source-line-no">5467</span><span id="line-5467"> // table durability(SYNC,FSYNC,ASYC,SKIP,USE_DEFAULT) x mutation</span>
<span class="source-line-no">5468</span><span id="line-5468"> // durability(SYNC,FSYNC,ASYC,SKIP,USE_DEFAULT)</span>
<span class="source-line-no">5469</span><span id="line-5469"></span>
<span class="source-line-no">5470</span><span id="line-5470"> // expected cases for append and sync wal</span>
<span class="source-line-no">5471</span><span id="line-5471"> durabilityTest(method, Durability.SYNC_WAL, Durability.SYNC_WAL, 0, true, true, false);</span>
<span class="source-line-no">5472</span><span id="line-5472"> durabilityTest(method, Durability.SYNC_WAL, Durability.FSYNC_WAL, 0, true, true, false);</span>
<span class="source-line-no">5473</span><span id="line-5473"> durabilityTest(method, Durability.SYNC_WAL, Durability.USE_DEFAULT, 0, true, true, false);</span>
<span class="source-line-no">5474</span><span id="line-5474"></span>
<span class="source-line-no">5475</span><span id="line-5475"> durabilityTest(method, Durability.FSYNC_WAL, Durability.SYNC_WAL, 0, true, true, false);</span>
<span class="source-line-no">5476</span><span id="line-5476"> durabilityTest(method, Durability.FSYNC_WAL, Durability.FSYNC_WAL, 0, true, true, false);</span>
<span class="source-line-no">5477</span><span id="line-5477"> durabilityTest(method, Durability.FSYNC_WAL, Durability.USE_DEFAULT, 0, true, true, false);</span>
<span class="source-line-no">5478</span><span id="line-5478"></span>
<span class="source-line-no">5479</span><span id="line-5479"> durabilityTest(method, Durability.ASYNC_WAL, Durability.SYNC_WAL, 0, true, true, false);</span>
<span class="source-line-no">5480</span><span id="line-5480"> durabilityTest(method, Durability.ASYNC_WAL, Durability.FSYNC_WAL, 0, true, true, false);</span>
<span class="source-line-no">5481</span><span id="line-5481"></span>
<span class="source-line-no">5482</span><span id="line-5482"> durabilityTest(method, Durability.SKIP_WAL, Durability.SYNC_WAL, 0, true, true, false);</span>
<span class="source-line-no">5483</span><span id="line-5483"> durabilityTest(method, Durability.SKIP_WAL, Durability.FSYNC_WAL, 0, true, true, false);</span>
<span class="source-line-no">5484</span><span id="line-5484"></span>
<span class="source-line-no">5485</span><span id="line-5485"> durabilityTest(method, Durability.USE_DEFAULT, Durability.SYNC_WAL, 0, true, true, false);</span>
<span class="source-line-no">5486</span><span id="line-5486"> durabilityTest(method, Durability.USE_DEFAULT, Durability.FSYNC_WAL, 0, true, true, false);</span>
<span class="source-line-no">5487</span><span id="line-5487"> durabilityTest(method, Durability.USE_DEFAULT, Durability.USE_DEFAULT, 0, true, true, false);</span>
<span class="source-line-no">5488</span><span id="line-5488"></span>
<span class="source-line-no">5489</span><span id="line-5489"> // expected cases for async wal</span>
<span class="source-line-no">5490</span><span id="line-5490"> durabilityTest(method, Durability.SYNC_WAL, Durability.ASYNC_WAL, 0, true, false, false);</span>
<span class="source-line-no">5491</span><span id="line-5491"> durabilityTest(method, Durability.FSYNC_WAL, Durability.ASYNC_WAL, 0, true, false, false);</span>
<span class="source-line-no">5492</span><span id="line-5492"> durabilityTest(method, Durability.ASYNC_WAL, Durability.ASYNC_WAL, 0, true, false, false);</span>
<span class="source-line-no">5493</span><span id="line-5493"> durabilityTest(method, Durability.SKIP_WAL, Durability.ASYNC_WAL, 0, true, false, false);</span>
<span class="source-line-no">5494</span><span id="line-5494"> durabilityTest(method, Durability.USE_DEFAULT, Durability.ASYNC_WAL, 0, true, false, false);</span>
<span class="source-line-no">5495</span><span id="line-5495"> durabilityTest(method, Durability.ASYNC_WAL, Durability.USE_DEFAULT, 0, true, false, false);</span>
<span class="source-line-no">5496</span><span id="line-5496"></span>
<span class="source-line-no">5497</span><span id="line-5497"> durabilityTest(method, Durability.SYNC_WAL, Durability.ASYNC_WAL, 5000, true, false, true);</span>
<span class="source-line-no">5498</span><span id="line-5498"> durabilityTest(method, Durability.FSYNC_WAL, Durability.ASYNC_WAL, 5000, true, false, true);</span>
<span class="source-line-no">5499</span><span id="line-5499"> durabilityTest(method, Durability.ASYNC_WAL, Durability.ASYNC_WAL, 5000, true, false, true);</span>
<span class="source-line-no">5500</span><span id="line-5500"> durabilityTest(method, Durability.SKIP_WAL, Durability.ASYNC_WAL, 5000, true, false, true);</span>
<span class="source-line-no">5501</span><span id="line-5501"> durabilityTest(method, Durability.USE_DEFAULT, Durability.ASYNC_WAL, 5000, true, false, true);</span>
<span class="source-line-no">5502</span><span id="line-5502"> durabilityTest(method, Durability.ASYNC_WAL, Durability.USE_DEFAULT, 5000, true, false, true);</span>
<span class="source-line-no">5503</span><span id="line-5503"></span>
<span class="source-line-no">5504</span><span id="line-5504"> // expect skip wal cases</span>
<span class="source-line-no">5505</span><span id="line-5505"> durabilityTest(method, Durability.SYNC_WAL, Durability.SKIP_WAL, 0, false, false, false);</span>
<span class="source-line-no">5506</span><span id="line-5506"> durabilityTest(method, Durability.FSYNC_WAL, Durability.SKIP_WAL, 0, false, false, false);</span>
<span class="source-line-no">5507</span><span id="line-5507"> durabilityTest(method, Durability.ASYNC_WAL, 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.SKIP_WAL, 0, false, false, false);</span>
<span class="source-line-no">5509</span><span id="line-5509"> durabilityTest(method, Durability.USE_DEFAULT, Durability.SKIP_WAL, 0, false, false, false);</span>
<span class="source-line-no">5510</span><span id="line-5510"> durabilityTest(method, Durability.SKIP_WAL, Durability.USE_DEFAULT, 0, false, false, false);</span>
<span class="source-line-no">5511</span><span id="line-5511"></span>
<span class="source-line-no">5512</span><span id="line-5512"> }</span>
<span class="source-line-no">5513</span><span id="line-5513"></span>
<span class="source-line-no">5514</span><span id="line-5514"> private void durabilityTest(String method, Durability tableDurability,</span>
<span class="source-line-no">5515</span><span id="line-5515"> Durability mutationDurability, long timeout, boolean expectAppend, final boolean expectSync,</span>
<span class="source-line-no">5516</span><span id="line-5516"> final boolean expectSyncFromLogSyncer) throws Exception {</span>
<span class="source-line-no">5517</span><span id="line-5517"> Configuration conf = HBaseConfiguration.create(CONF);</span>
<span class="source-line-no">5518</span><span id="line-5518"> conf.setLong(AbstractFSWAL.WAL_SHUTDOWN_WAIT_TIMEOUT_MS, 60 * 60 * 1000);</span>
<span class="source-line-no">5519</span><span id="line-5519"> method = method + "_" + tableDurability.name() + "_" + mutationDurability.name();</span>
<span class="source-line-no">5520</span><span id="line-5520"> byte[] family = Bytes.toBytes("family");</span>
<span class="source-line-no">5521</span><span id="line-5521"> Path logDir = new Path(new Path(dir + method), "log");</span>
<span class="source-line-no">5522</span><span id="line-5522"> final Configuration walConf = new Configuration(conf);</span>
<span class="source-line-no">5523</span><span id="line-5523"> CommonFSUtils.setRootDir(walConf, logDir);</span>
<span class="source-line-no">5524</span><span id="line-5524"> // XXX: The spied AsyncFSWAL can not work properly because of a Mockito defect that can not</span>
<span class="source-line-no">5525</span><span id="line-5525"> // deal with classes which have a field of an inner class. See discussions in HBASE-15536.</span>
<span class="source-line-no">5526</span><span id="line-5526"> walConf.set(WALFactory.WAL_PROVIDER, "filesystem");</span>
<span class="source-line-no">5527</span><span id="line-5527"> final WALFactory wals = new WALFactory(walConf, HBaseTestingUtil.getRandomUUID().toString());</span>
<span class="source-line-no">5528</span><span id="line-5528"> final WAL wal = spy(wals.getWAL(RegionInfoBuilder.newBuilder(tableName).build()));</span>
<span class="source-line-no">5529</span><span id="line-5529"> this.region = initHRegion(tableName, HConstants.EMPTY_START_ROW, HConstants.EMPTY_END_ROW, CONF,</span>
<span class="source-line-no">5530</span><span id="line-5530"> false, tableDurability, wal, new byte[][] { family });</span>
<span class="source-line-no">5531</span><span id="line-5531"></span>
<span class="source-line-no">5532</span><span id="line-5532"> Put put = new Put(Bytes.toBytes("r1"));</span>
<span class="source-line-no">5533</span><span id="line-5533"> put.addColumn(family, Bytes.toBytes("q1"), Bytes.toBytes("v1"));</span>
<span class="source-line-no">5534</span><span id="line-5534"> put.setDurability(mutationDurability);</span>
<span class="source-line-no">5535</span><span id="line-5535"> region.put(put);</span>
<span class="source-line-no">5536</span><span id="line-5536"></span>
<span class="source-line-no">5537</span><span id="line-5537"> // verify append called or not</span>
<span class="source-line-no">5538</span><span id="line-5538"> verify(wal, expectAppend ? times(1) : never()).appendData((RegionInfo) any(),</span>
<span class="source-line-no">5539</span><span id="line-5539"> (WALKeyImpl) any(), (WALEdit) any());</span>
<span class="source-line-no">5540</span><span id="line-5540"></span>
<span class="source-line-no">5541</span><span id="line-5541"> // verify sync called or not</span>
<span class="source-line-no">5542</span><span id="line-5542"> if (expectSync || expectSyncFromLogSyncer) {</span>
<span class="source-line-no">5543</span><span id="line-5543"> TEST_UTIL.waitFor(timeout, new Waiter.Predicate&lt;Exception&gt;() {</span>
<span class="source-line-no">5544</span><span id="line-5544"> @Override</span>
<span class="source-line-no">5545</span><span id="line-5545"> public boolean evaluate() throws Exception {</span>
<span class="source-line-no">5546</span><span id="line-5546"> try {</span>
<span class="source-line-no">5547</span><span id="line-5547"> if (expectSync) {</span>
<span class="source-line-no">5548</span><span id="line-5548"> verify(wal, times(1)).sync(anyLong()); // Hregion calls this one</span>
<span class="source-line-no">5549</span><span id="line-5549"> } else if (expectSyncFromLogSyncer) {</span>
<span class="source-line-no">5550</span><span id="line-5550"> verify(wal, times(1)).sync(); // wal syncer calls this one</span>
<span class="source-line-no">5551</span><span id="line-5551"> }</span>
<span class="source-line-no">5552</span><span id="line-5552"> } catch (Throwable ignore) {</span>
<span class="source-line-no">5553</span><span id="line-5553"> }</span>
<span class="source-line-no">5554</span><span id="line-5554"> return true;</span>
<span class="source-line-no">5555</span><span id="line-5555"> }</span>
<span class="source-line-no">5556</span><span id="line-5556"> });</span>
<span class="source-line-no">5557</span><span id="line-5557"> } else {</span>
<span class="source-line-no">5558</span><span id="line-5558"> // verify(wal, never()).sync(anyLong());</span>
<span class="source-line-no">5559</span><span id="line-5559"> verify(wal, never()).sync();</span>
<span class="source-line-no">5560</span><span id="line-5560"> }</span>
<span class="source-line-no">5561</span><span id="line-5561"></span>
<span class="source-line-no">5562</span><span id="line-5562"> HBaseTestingUtil.closeRegionAndWAL(this.region);</span>
<span class="source-line-no">5563</span><span id="line-5563"> wals.close();</span>
<span class="source-line-no">5564</span><span id="line-5564"> this.region = null;</span>
<span class="source-line-no">5565</span><span id="line-5565"> }</span>
<span class="source-line-no">5566</span><span id="line-5566"></span>
<span class="source-line-no">5567</span><span id="line-5567"> @Test</span>
<span class="source-line-no">5568</span><span id="line-5568"> public void testRegionReplicaSecondary() throws IOException {</span>
<span class="source-line-no">5569</span><span id="line-5569"> // create a primary region, load some data and flush</span>
<span class="source-line-no">5570</span><span id="line-5570"> // create a secondary region, and do a get against that</span>
<span class="source-line-no">5571</span><span id="line-5571"> Path rootDir = new Path(dir + name.getMethodName());</span>
<span class="source-line-no">5572</span><span id="line-5572"> CommonFSUtils.setRootDir(TEST_UTIL.getConfiguration(), rootDir);</span>
<span class="source-line-no">5573</span><span id="line-5573"></span>
<span class="source-line-no">5574</span><span id="line-5574"> byte[][] families =</span>
<span class="source-line-no">5575</span><span id="line-5575"> new byte[][] { Bytes.toBytes("cf1"), Bytes.toBytes("cf2"), Bytes.toBytes("cf3") };</span>
<span class="source-line-no">5576</span><span id="line-5576"> byte[] cq = Bytes.toBytes("cq");</span>
<span class="source-line-no">5577</span><span id="line-5577"> TableDescriptorBuilder builder =</span>
<span class="source-line-no">5578</span><span id="line-5578"> TableDescriptorBuilder.newBuilder(TableName.valueOf(name.getMethodName()));</span>
<span class="source-line-no">5579</span><span id="line-5579"> for (byte[] family : families) {</span>
<span class="source-line-no">5580</span><span id="line-5580"> builder.setColumnFamily(ColumnFamilyDescriptorBuilder.of(family));</span>
<span class="source-line-no">5581</span><span id="line-5581"> }</span>
<span class="source-line-no">5582</span><span id="line-5582"> TableDescriptor tableDescriptor = builder.build();</span>
<span class="source-line-no">5583</span><span id="line-5583"> long time = EnvironmentEdgeManager.currentTime();</span>
<span class="source-line-no">5584</span><span id="line-5584"> RegionInfo primaryHri = RegionInfoBuilder.newBuilder(tableDescriptor.getTableName())</span>
<span class="source-line-no">5585</span><span id="line-5585"> .setRegionId(time).setReplicaId(0).build();</span>
<span class="source-line-no">5586</span><span id="line-5586"> RegionInfo secondaryHri = RegionInfoBuilder.newBuilder(tableDescriptor.getTableName())</span>
<span class="source-line-no">5587</span><span id="line-5587"> .setRegionId(time).setReplicaId(1).build();</span>
<span class="source-line-no">5588</span><span id="line-5588"></span>
<span class="source-line-no">5589</span><span id="line-5589"> HRegion primaryRegion = null, secondaryRegion = null;</span>
<span class="source-line-no">5590</span><span id="line-5590"></span>
<span class="source-line-no">5591</span><span id="line-5591"> try {</span>
<span class="source-line-no">5592</span><span id="line-5592"> primaryRegion = HBaseTestingUtil.createRegionAndWAL(primaryHri, rootDir,</span>
<span class="source-line-no">5593</span><span id="line-5593"> TEST_UTIL.getConfiguration(), tableDescriptor);</span>
<span class="source-line-no">5594</span><span id="line-5594"></span>
<span class="source-line-no">5595</span><span id="line-5595"> // load some data</span>
<span class="source-line-no">5596</span><span id="line-5596"> putData(primaryRegion, 0, 1000, cq, families);</span>
<span class="source-line-no">5597</span><span id="line-5597"></span>
<span class="source-line-no">5598</span><span id="line-5598"> // flush region</span>
<span class="source-line-no">5599</span><span id="line-5599"> primaryRegion.flush(true);</span>
<span class="source-line-no">5600</span><span id="line-5600"></span>
<span class="source-line-no">5601</span><span id="line-5601"> // open secondary region</span>
<span class="source-line-no">5602</span><span id="line-5602"> secondaryRegion = HRegion.openHRegion(rootDir, secondaryHri, tableDescriptor, null, CONF);</span>
<span class="source-line-no">5603</span><span id="line-5603"></span>
<span class="source-line-no">5604</span><span id="line-5604"> verifyData(secondaryRegion, 0, 1000, cq, families);</span>
<span class="source-line-no">5605</span><span id="line-5605"> } finally {</span>
<span class="source-line-no">5606</span><span id="line-5606"> if (primaryRegion != null) {</span>
<span class="source-line-no">5607</span><span id="line-5607"> HBaseTestingUtil.closeRegionAndWAL(primaryRegion);</span>
<span class="source-line-no">5608</span><span id="line-5608"> }</span>
<span class="source-line-no">5609</span><span id="line-5609"> if (secondaryRegion != null) {</span>
<span class="source-line-no">5610</span><span id="line-5610"> HBaseTestingUtil.closeRegionAndWAL(secondaryRegion);</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"> }</span>
<span class="source-line-no">5614</span><span id="line-5614"></span>
<span class="source-line-no">5615</span><span id="line-5615"> @Test</span>
<span class="source-line-no">5616</span><span id="line-5616"> public void testRegionReplicaSecondaryIsReadOnly() throws IOException {</span>
<span class="source-line-no">5617</span><span id="line-5617"> // create a primary region, load some data and flush</span>
<span class="source-line-no">5618</span><span id="line-5618"> // create a secondary region, and do a put against that</span>
<span class="source-line-no">5619</span><span id="line-5619"> Path rootDir = new Path(dir + name.getMethodName());</span>
<span class="source-line-no">5620</span><span id="line-5620"> CommonFSUtils.setRootDir(TEST_UTIL.getConfiguration(), rootDir);</span>
<span class="source-line-no">5621</span><span id="line-5621"></span>
<span class="source-line-no">5622</span><span id="line-5622"> byte[][] families =</span>
<span class="source-line-no">5623</span><span id="line-5623"> new byte[][] { Bytes.toBytes("cf1"), Bytes.toBytes("cf2"), Bytes.toBytes("cf3") };</span>
<span class="source-line-no">5624</span><span id="line-5624"> byte[] cq = Bytes.toBytes("cq");</span>
<span class="source-line-no">5625</span><span id="line-5625"> TableDescriptorBuilder builder =</span>
<span class="source-line-no">5626</span><span id="line-5626"> TableDescriptorBuilder.newBuilder(TableName.valueOf(name.getMethodName()));</span>
<span class="source-line-no">5627</span><span id="line-5627"> for (byte[] family : families) {</span>
<span class="source-line-no">5628</span><span id="line-5628"> builder.setColumnFamily(ColumnFamilyDescriptorBuilder.of(family));</span>
<span class="source-line-no">5629</span><span id="line-5629"> }</span>
<span class="source-line-no">5630</span><span id="line-5630"> TableDescriptor tableDescriptor = builder.build();</span>
<span class="source-line-no">5631</span><span id="line-5631"> long time = EnvironmentEdgeManager.currentTime();</span>
<span class="source-line-no">5632</span><span id="line-5632"> RegionInfo primaryHri = RegionInfoBuilder.newBuilder(tableDescriptor.getTableName())</span>
<span class="source-line-no">5633</span><span id="line-5633"> .setRegionId(time).setReplicaId(0).build();</span>
<span class="source-line-no">5634</span><span id="line-5634"> RegionInfo secondaryHri = RegionInfoBuilder.newBuilder(tableDescriptor.getTableName())</span>
<span class="source-line-no">5635</span><span id="line-5635"> .setRegionId(time).setReplicaId(1).build();</span>
<span class="source-line-no">5636</span><span id="line-5636"></span>
<span class="source-line-no">5637</span><span id="line-5637"> HRegion primaryRegion = null, secondaryRegion = null;</span>
<span class="source-line-no">5638</span><span id="line-5638"></span>
<span class="source-line-no">5639</span><span id="line-5639"> try {</span>
<span class="source-line-no">5640</span><span id="line-5640"> primaryRegion = HBaseTestingUtil.createRegionAndWAL(primaryHri, rootDir,</span>
<span class="source-line-no">5641</span><span id="line-5641"> TEST_UTIL.getConfiguration(), tableDescriptor);</span>
<span class="source-line-no">5642</span><span id="line-5642"></span>
<span class="source-line-no">5643</span><span id="line-5643"> // load some data</span>
<span class="source-line-no">5644</span><span id="line-5644"> putData(primaryRegion, 0, 1000, cq, families);</span>
<span class="source-line-no">5645</span><span id="line-5645"></span>
<span class="source-line-no">5646</span><span id="line-5646"> // flush region</span>
<span class="source-line-no">5647</span><span id="line-5647"> primaryRegion.flush(true);</span>
<span class="source-line-no">5648</span><span id="line-5648"></span>
<span class="source-line-no">5649</span><span id="line-5649"> // open secondary region</span>
<span class="source-line-no">5650</span><span id="line-5650"> secondaryRegion = HRegion.openHRegion(rootDir, secondaryHri, tableDescriptor, null, CONF);</span>
<span class="source-line-no">5651</span><span id="line-5651"></span>
<span class="source-line-no">5652</span><span id="line-5652"> try {</span>
<span class="source-line-no">5653</span><span id="line-5653"> putData(secondaryRegion, 0, 1000, cq, families);</span>
<span class="source-line-no">5654</span><span id="line-5654"> fail("Should have thrown exception");</span>
<span class="source-line-no">5655</span><span id="line-5655"> } catch (IOException ex) {</span>
<span class="source-line-no">5656</span><span id="line-5656"> // expected</span>
<span class="source-line-no">5657</span><span id="line-5657"> }</span>
<span class="source-line-no">5658</span><span id="line-5658"> } finally {</span>
<span class="source-line-no">5659</span><span id="line-5659"> if (primaryRegion != null) {</span>
<span class="source-line-no">5660</span><span id="line-5660"> HBaseTestingUtil.closeRegionAndWAL(primaryRegion);</span>
<span class="source-line-no">5661</span><span id="line-5661"> }</span>
<span class="source-line-no">5662</span><span id="line-5662"> if (secondaryRegion != null) {</span>
<span class="source-line-no">5663</span><span id="line-5663"> HBaseTestingUtil.closeRegionAndWAL(secondaryRegion);</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"> }</span>
<span class="source-line-no">5667</span><span id="line-5667"></span>
<span class="source-line-no">5668</span><span id="line-5668"> static WALFactory createWALFactory(Configuration conf, Path rootDir) throws IOException {</span>
<span class="source-line-no">5669</span><span id="line-5669"> Configuration confForWAL = new Configuration(conf);</span>
<span class="source-line-no">5670</span><span id="line-5670"> confForWAL.set(HConstants.HBASE_DIR, rootDir.toString());</span>
<span class="source-line-no">5671</span><span id="line-5671"> return new WALFactory(confForWAL, "hregion-" + RandomStringUtils.randomNumeric(8));</span>
<span class="source-line-no">5672</span><span id="line-5672"> }</span>
<span class="source-line-no">5673</span><span id="line-5673"></span>
<span class="source-line-no">5674</span><span id="line-5674"> @Test</span>
<span class="source-line-no">5675</span><span id="line-5675"> public void testCompactionFromPrimary() throws IOException {</span>
<span class="source-line-no">5676</span><span id="line-5676"> Path rootDir = new Path(dir + name.getMethodName());</span>
<span class="source-line-no">5677</span><span id="line-5677"> CommonFSUtils.setRootDir(TEST_UTIL.getConfiguration(), rootDir);</span>
<span class="source-line-no">5678</span><span id="line-5678"></span>
<span class="source-line-no">5679</span><span id="line-5679"> byte[][] families =</span>
<span class="source-line-no">5680</span><span id="line-5680"> new byte[][] { Bytes.toBytes("cf1"), Bytes.toBytes("cf2"), Bytes.toBytes("cf3") };</span>
<span class="source-line-no">5681</span><span id="line-5681"> byte[] cq = Bytes.toBytes("cq");</span>
<span class="source-line-no">5682</span><span id="line-5682"> TableDescriptorBuilder builder =</span>
<span class="source-line-no">5683</span><span id="line-5683"> TableDescriptorBuilder.newBuilder(TableName.valueOf(name.getMethodName()));</span>
<span class="source-line-no">5684</span><span id="line-5684"> for (byte[] family : families) {</span>
<span class="source-line-no">5685</span><span id="line-5685"> builder.setColumnFamily(ColumnFamilyDescriptorBuilder.of(family));</span>
<span class="source-line-no">5686</span><span id="line-5686"> }</span>
<span class="source-line-no">5687</span><span id="line-5687"> TableDescriptor tableDescriptor = builder.build();</span>
<span class="source-line-no">5688</span><span id="line-5688"> long time = EnvironmentEdgeManager.currentTime();</span>
<span class="source-line-no">5689</span><span id="line-5689"> RegionInfo primaryHri = RegionInfoBuilder.newBuilder(tableDescriptor.getTableName())</span>
<span class="source-line-no">5690</span><span id="line-5690"> .setRegionId(time).setReplicaId(0).build();</span>
<span class="source-line-no">5691</span><span id="line-5691"> RegionInfo secondaryHri = RegionInfoBuilder.newBuilder(tableDescriptor.getTableName())</span>
<span class="source-line-no">5692</span><span id="line-5692"> .setRegionId(time).setReplicaId(1).build();</span>
<span class="source-line-no">5693</span><span id="line-5693"></span>
<span class="source-line-no">5694</span><span id="line-5694"> HRegion primaryRegion = null, secondaryRegion = null;</span>
<span class="source-line-no">5695</span><span id="line-5695"></span>
<span class="source-line-no">5696</span><span id="line-5696"> try {</span>
<span class="source-line-no">5697</span><span id="line-5697"> primaryRegion = HBaseTestingUtil.createRegionAndWAL(primaryHri, rootDir,</span>
<span class="source-line-no">5698</span><span id="line-5698"> TEST_UTIL.getConfiguration(), tableDescriptor);</span>
<span class="source-line-no">5699</span><span id="line-5699"></span>
<span class="source-line-no">5700</span><span id="line-5700"> // load some data</span>
<span class="source-line-no">5701</span><span id="line-5701"> putData(primaryRegion, 0, 1000, cq, families);</span>
<span class="source-line-no">5702</span><span id="line-5702"></span>
<span class="source-line-no">5703</span><span id="line-5703"> // flush region</span>
<span class="source-line-no">5704</span><span id="line-5704"> primaryRegion.flush(true);</span>
<span class="source-line-no">5705</span><span id="line-5705"></span>
<span class="source-line-no">5706</span><span id="line-5706"> // open secondary region</span>
<span class="source-line-no">5707</span><span id="line-5707"> secondaryRegion = HRegion.openHRegion(rootDir, secondaryHri, tableDescriptor, null, CONF);</span>
<span class="source-line-no">5708</span><span id="line-5708"></span>
<span class="source-line-no">5709</span><span id="line-5709"> // move the file of the primary region to the archive, simulating a compaction</span>
<span class="source-line-no">5710</span><span id="line-5710"> Collection&lt;HStoreFile&gt; storeFiles = primaryRegion.getStore(families[0]).getStorefiles();</span>
<span class="source-line-no">5711</span><span id="line-5711"> primaryRegion.getRegionFileSystem().removeStoreFiles(Bytes.toString(families[0]), storeFiles);</span>
<span class="source-line-no">5712</span><span id="line-5712"> Collection&lt;StoreFileInfo&gt; storeFileInfos =</span>
<span class="source-line-no">5713</span><span id="line-5713"> primaryRegion.getRegionFileSystem().getStoreFiles(Bytes.toString(families[0]));</span>
<span class="source-line-no">5714</span><span id="line-5714"> Assert.assertTrue(storeFileInfos == null || storeFileInfos.isEmpty());</span>
<span class="source-line-no">5715</span><span id="line-5715"></span>
<span class="source-line-no">5716</span><span id="line-5716"> verifyData(secondaryRegion, 0, 1000, cq, families);</span>
<span class="source-line-no">5717</span><span id="line-5717"> } finally {</span>
<span class="source-line-no">5718</span><span id="line-5718"> if (primaryRegion != null) {</span>
<span class="source-line-no">5719</span><span id="line-5719"> HBaseTestingUtil.closeRegionAndWAL(primaryRegion);</span>
<span class="source-line-no">5720</span><span id="line-5720"> }</span>
<span class="source-line-no">5721</span><span id="line-5721"> if (secondaryRegion != null) {</span>
<span class="source-line-no">5722</span><span id="line-5722"> HBaseTestingUtil.closeRegionAndWAL(secondaryRegion);</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"> }</span>
<span class="source-line-no">5726</span><span id="line-5726"></span>
<span class="source-line-no">5727</span><span id="line-5727"> private void putData(int startRow, int numRows, byte[] qf, byte[]... families)</span>
<span class="source-line-no">5728</span><span id="line-5728"> throws IOException {</span>
<span class="source-line-no">5729</span><span id="line-5729"> putData(this.region, startRow, numRows, qf, families);</span>
<span class="source-line-no">5730</span><span id="line-5730"> }</span>
<span class="source-line-no">5731</span><span id="line-5731"></span>
<span class="source-line-no">5732</span><span id="line-5732"> private void putData(HRegion region, int startRow, int numRows, byte[] qf, byte[]... families)</span>
<span class="source-line-no">5733</span><span id="line-5733"> throws IOException {</span>
<span class="source-line-no">5734</span><span id="line-5734"> putData(region, Durability.SKIP_WAL, startRow, numRows, qf, families);</span>
<span class="source-line-no">5735</span><span id="line-5735"> }</span>
<span class="source-line-no">5736</span><span id="line-5736"></span>
<span class="source-line-no">5737</span><span id="line-5737"> static void putData(HRegion region, Durability durability, int startRow, int numRows, byte[] qf,</span>
<span class="source-line-no">5738</span><span id="line-5738"> byte[]... families) throws IOException {</span>
<span class="source-line-no">5739</span><span id="line-5739"> for (int i = startRow; i &lt; startRow + numRows; i++) {</span>
<span class="source-line-no">5740</span><span id="line-5740"> Put put = new Put(Bytes.toBytes("" + i));</span>
<span class="source-line-no">5741</span><span id="line-5741"> put.setDurability(durability);</span>
<span class="source-line-no">5742</span><span id="line-5742"> for (byte[] family : families) {</span>
<span class="source-line-no">5743</span><span id="line-5743"> put.addColumn(family, qf, null);</span>
<span class="source-line-no">5744</span><span id="line-5744"> }</span>
<span class="source-line-no">5745</span><span id="line-5745"> region.put(put);</span>
<span class="source-line-no">5746</span><span id="line-5746"> LOG.info(put.toString());</span>
<span class="source-line-no">5747</span><span id="line-5747"> }</span>
<span class="source-line-no">5748</span><span id="line-5748"> }</span>
<span class="source-line-no">5749</span><span id="line-5749"></span>
<span class="source-line-no">5750</span><span id="line-5750"> static void verifyData(HRegion newReg, int startRow, int numRows, byte[] qf, byte[]... families)</span>
<span class="source-line-no">5751</span><span id="line-5751"> throws IOException {</span>
<span class="source-line-no">5752</span><span id="line-5752"> for (int i = startRow; i &lt; startRow + numRows; i++) {</span>
<span class="source-line-no">5753</span><span id="line-5753"> byte[] row = Bytes.toBytes("" + i);</span>
<span class="source-line-no">5754</span><span id="line-5754"> Get get = new Get(row);</span>
<span class="source-line-no">5755</span><span id="line-5755"> for (byte[] family : families) {</span>
<span class="source-line-no">5756</span><span id="line-5756"> get.addColumn(family, qf);</span>
<span class="source-line-no">5757</span><span id="line-5757"> }</span>
<span class="source-line-no">5758</span><span id="line-5758"> Result result = newReg.get(get);</span>
<span class="source-line-no">5759</span><span id="line-5759"> Cell[] raw = result.rawCells();</span>
<span class="source-line-no">5760</span><span id="line-5760"> assertEquals(families.length, result.size());</span>
<span class="source-line-no">5761</span><span id="line-5761"> for (int j = 0; j &lt; families.length; j++) {</span>
<span class="source-line-no">5762</span><span id="line-5762"> assertTrue(CellUtil.matchingRows(raw[j], row));</span>
<span class="source-line-no">5763</span><span id="line-5763"> assertTrue(CellUtil.matchingFamily(raw[j], families[j]));</span>
<span class="source-line-no">5764</span><span id="line-5764"> assertTrue(CellUtil.matchingQualifier(raw[j], qf));</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"> }</span>
<span class="source-line-no">5768</span><span id="line-5768"></span>
<span class="source-line-no">5769</span><span id="line-5769"> static void assertGet(final HRegion r, final byte[] family, final byte[] k) throws IOException {</span>
<span class="source-line-no">5770</span><span id="line-5770"> // Now I have k, get values out and assert they are as expected.</span>
<span class="source-line-no">5771</span><span id="line-5771"> Get get = new Get(k).addFamily(family).readAllVersions();</span>
<span class="source-line-no">5772</span><span id="line-5772"> Cell[] results = r.get(get).rawCells();</span>
<span class="source-line-no">5773</span><span id="line-5773"> for (int j = 0; j &lt; results.length; j++) {</span>
<span class="source-line-no">5774</span><span id="line-5774"> byte[] tmp = CellUtil.cloneValue(results[j]);</span>
<span class="source-line-no">5775</span><span id="line-5775"> // Row should be equal to value every time.</span>
<span class="source-line-no">5776</span><span id="line-5776"> assertTrue(Bytes.equals(k, tmp));</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"></span>
<span class="source-line-no">5780</span><span id="line-5780"> /*</span>
<span class="source-line-no">5781</span><span id="line-5781"> * Assert first value in the passed region is &lt;code&gt;firstValue&lt;/code&gt;.</span>
<span class="source-line-no">5782</span><span id="line-5782"> */</span>
<span class="source-line-no">5783</span><span id="line-5783"> protected void assertScan(final HRegion r, final byte[] fs, final byte[] firstValue)</span>
<span class="source-line-no">5784</span><span id="line-5784"> throws IOException {</span>
<span class="source-line-no">5785</span><span id="line-5785"> byte[][] families = { fs };</span>
<span class="source-line-no">5786</span><span id="line-5786"> Scan scan = new Scan();</span>
<span class="source-line-no">5787</span><span id="line-5787"> for (int i = 0; i &lt; families.length; i++)</span>
<span class="source-line-no">5788</span><span id="line-5788"> scan.addFamily(families[i]);</span>
<span class="source-line-no">5789</span><span id="line-5789"> try (InternalScanner s = r.getScanner(scan)) {</span>
<span class="source-line-no">5790</span><span id="line-5790"> List&lt;Cell&gt; curVals = new ArrayList&lt;&gt;();</span>
<span class="source-line-no">5791</span><span id="line-5791"> boolean first = true;</span>
<span class="source-line-no">5792</span><span id="line-5792"> OUTER_LOOP: while (s.next(curVals)) {</span>
<span class="source-line-no">5793</span><span id="line-5793"> for (Cell kv : curVals) {</span>
<span class="source-line-no">5794</span><span id="line-5794"> byte[] val = CellUtil.cloneValue(kv);</span>
<span class="source-line-no">5795</span><span id="line-5795"> byte[] curval = val;</span>
<span class="source-line-no">5796</span><span id="line-5796"> if (first) {</span>
<span class="source-line-no">5797</span><span id="line-5797"> first = false;</span>
<span class="source-line-no">5798</span><span id="line-5798"> assertTrue(Bytes.compareTo(curval, firstValue) == 0);</span>
<span class="source-line-no">5799</span><span id="line-5799"> } else {</span>
<span class="source-line-no">5800</span><span id="line-5800"> // Not asserting anything. Might as well break.</span>
<span class="source-line-no">5801</span><span id="line-5801"> break OUTER_LOOP;</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"></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 that we get the expected flush results back</span>
<span class="source-line-no">5810</span><span id="line-5810"> */</span>
<span class="source-line-no">5811</span><span id="line-5811"> @Test</span>
<span class="source-line-no">5812</span><span id="line-5812"> public void testFlushResult() throws IOException {</span>
<span class="source-line-no">5813</span><span id="line-5813"> byte[] family = Bytes.toBytes("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"> this.region = initHRegion(tableName, method, family);</span>
<span class="source-line-no">5816</span><span id="line-5816"></span>
<span class="source-line-no">5817</span><span id="line-5817"> // empty memstore, flush doesn't run</span>
<span class="source-line-no">5818</span><span id="line-5818"> HRegion.FlushResult fr = region.flush(true);</span>
<span class="source-line-no">5819</span><span id="line-5819"> assertFalse(fr.isFlushSucceeded());</span>
<span class="source-line-no">5820</span><span id="line-5820"> assertFalse(fr.isCompactionNeeded());</span>
<span class="source-line-no">5821</span><span id="line-5821"></span>
<span class="source-line-no">5822</span><span id="line-5822"> // Flush enough files to get up to the threshold, doesn't need compactions</span>
<span class="source-line-no">5823</span><span id="line-5823"> for (int i = 0; i &lt; 2; i++) {</span>
<span class="source-line-no">5824</span><span id="line-5824"> Put put = new Put(tableName.toBytes()).addColumn(family, family, tableName.toBytes());</span>
<span class="source-line-no">5825</span><span id="line-5825"> region.put(put);</span>
<span class="source-line-no">5826</span><span id="line-5826"> fr = region.flush(true);</span>
<span class="source-line-no">5827</span><span id="line-5827"> assertTrue(fr.isFlushSucceeded());</span>
<span class="source-line-no">5828</span><span id="line-5828"> assertFalse(fr.isCompactionNeeded());</span>
<span class="source-line-no">5829</span><span id="line-5829"> }</span>
<span class="source-line-no">5830</span><span id="line-5830"></span>
<span class="source-line-no">5831</span><span id="line-5831"> // Two flushes after the threshold, compactions are needed</span>
<span class="source-line-no">5832</span><span id="line-5832"> for (int i = 0; i &lt; 2; i++) {</span>
<span class="source-line-no">5833</span><span id="line-5833"> Put put = new Put(tableName.toBytes()).addColumn(family, family, tableName.toBytes());</span>
<span class="source-line-no">5834</span><span id="line-5834"> region.put(put);</span>
<span class="source-line-no">5835</span><span id="line-5835"> fr = region.flush(true);</span>
<span class="source-line-no">5836</span><span id="line-5836"> assertTrue(fr.isFlushSucceeded());</span>
<span class="source-line-no">5837</span><span id="line-5837"> assertTrue(fr.isCompactionNeeded());</span>
<span class="source-line-no">5838</span><span id="line-5838"> }</span>
<span class="source-line-no">5839</span><span id="line-5839"> }</span>
<span class="source-line-no">5840</span><span id="line-5840"></span>
<span class="source-line-no">5841</span><span id="line-5841"> protected Configuration initSplit() {</span>
<span class="source-line-no">5842</span><span id="line-5842"> // Always compact if there is more than one store file.</span>
<span class="source-line-no">5843</span><span id="line-5843"> CONF.setInt("hbase.hstore.compactionThreshold", 2);</span>
<span class="source-line-no">5844</span><span id="line-5844"></span>
<span class="source-line-no">5845</span><span id="line-5845"> CONF.setInt(HConstants.HBASE_CLIENT_SCANNER_TIMEOUT_PERIOD, 10 * 1000);</span>
<span class="source-line-no">5846</span><span id="line-5846"></span>
<span class="source-line-no">5847</span><span id="line-5847"> // Increase the amount of time between client retries</span>
<span class="source-line-no">5848</span><span id="line-5848"> CONF.setLong("hbase.client.pause", 15 * 1000);</span>
<span class="source-line-no">5849</span><span id="line-5849"></span>
<span class="source-line-no">5850</span><span id="line-5850"> // This size should make it so we always split using the addContent</span>
<span class="source-line-no">5851</span><span id="line-5851"> // below. After adding all data, the first region is 1.3M</span>
<span class="source-line-no">5852</span><span id="line-5852"> CONF.setLong(HConstants.HREGION_MAX_FILESIZE, 1024 * 128);</span>
<span class="source-line-no">5853</span><span id="line-5853"> return CONF;</span>
<span class="source-line-no">5854</span><span id="line-5854"> }</span>
<span class="source-line-no">5855</span><span id="line-5855"></span>
<span class="source-line-no">5856</span><span id="line-5856"> /**</span>
<span class="source-line-no">5857</span><span id="line-5857"> * @return A region on which you must call {@link HBaseTestingUtil#closeRegionAndWAL(HRegion)}</span>
<span class="source-line-no">5858</span><span id="line-5858"> * when done.</span>
<span class="source-line-no">5859</span><span id="line-5859"> */</span>
<span class="source-line-no">5860</span><span id="line-5860"> protected HRegion initHRegion(TableName tableName, String callingMethod, Configuration conf,</span>
<span class="source-line-no">5861</span><span id="line-5861"> byte[]... families) throws IOException {</span>
<span class="source-line-no">5862</span><span id="line-5862"> return initHRegion(tableName, callingMethod, conf, false, families);</span>
<span class="source-line-no">5863</span><span id="line-5863"> }</span>
<span class="source-line-no">5864</span><span id="line-5864"></span>
<span class="source-line-no">5865</span><span id="line-5865"> /**</span>
<span class="source-line-no">5866</span><span id="line-5866"> * @return A region on which you must call {@link HBaseTestingUtil#closeRegionAndWAL(HRegion)}</span>
<span class="source-line-no">5867</span><span id="line-5867"> * when done.</span>
<span class="source-line-no">5868</span><span id="line-5868"> */</span>
<span class="source-line-no">5869</span><span id="line-5869"> private HRegion initHRegion(TableName tableName, String callingMethod, Configuration conf,</span>
<span class="source-line-no">5870</span><span id="line-5870"> boolean isReadOnly, byte[]... families) throws IOException {</span>
<span class="source-line-no">5871</span><span id="line-5871"> return initHRegion(tableName, null, null, callingMethod, conf, isReadOnly, families);</span>
<span class="source-line-no">5872</span><span id="line-5872"> }</span>
<span class="source-line-no">5873</span><span id="line-5873"></span>
<span class="source-line-no">5874</span><span id="line-5874"> private HRegion initHRegion(TableName tableName, byte[] startKey, byte[] stopKey,</span>
<span class="source-line-no">5875</span><span id="line-5875"> String callingMethod, Configuration conf, boolean isReadOnly, byte[]... families)</span>
<span class="source-line-no">5876</span><span id="line-5876"> throws IOException {</span>
<span class="source-line-no">5877</span><span id="line-5877"> Path logDir = TEST_UTIL.getDataTestDirOnTestFS(callingMethod + ".log");</span>
<span class="source-line-no">5878</span><span id="line-5878"> RegionInfo hri =</span>
<span class="source-line-no">5879</span><span id="line-5879"> RegionInfoBuilder.newBuilder(tableName).setStartKey(startKey).setEndKey(stopKey).build();</span>
<span class="source-line-no">5880</span><span id="line-5880"> final WAL wal = HBaseTestingUtil.createWal(conf, logDir, hri);</span>
<span class="source-line-no">5881</span><span id="line-5881"> return initHRegion(tableName, startKey, stopKey, conf, isReadOnly, Durability.SYNC_WAL, wal,</span>
<span class="source-line-no">5882</span><span id="line-5882"> families);</span>
<span class="source-line-no">5883</span><span id="line-5883"> }</span>
<span class="source-line-no">5884</span><span id="line-5884"></span>
<span class="source-line-no">5885</span><span id="line-5885"> /**</span>
<span class="source-line-no">5886</span><span id="line-5886"> * @return A region on which you must call {@link HBaseTestingUtil#closeRegionAndWAL(HRegion)}</span>
<span class="source-line-no">5887</span><span id="line-5887"> * when done.</span>
<span class="source-line-no">5888</span><span id="line-5888"> */</span>
<span class="source-line-no">5889</span><span id="line-5889"> protected HRegion initHRegion(TableName tableName, byte[] startKey, byte[] stopKey,</span>
<span class="source-line-no">5890</span><span id="line-5890"> Configuration conf, boolean isReadOnly, Durability durability, WAL wal, byte[]... families)</span>
<span class="source-line-no">5891</span><span id="line-5891"> throws IOException {</span>
<span class="source-line-no">5892</span><span id="line-5892"> ChunkCreator.initialize(MemStoreLAB.CHUNK_SIZE_DEFAULT, false, 0, 0, 0, null,</span>
<span class="source-line-no">5893</span><span id="line-5893"> MemStoreLAB.INDEX_CHUNK_SIZE_PERCENTAGE_DEFAULT);</span>
<span class="source-line-no">5894</span><span id="line-5894"> return TEST_UTIL.createLocalHRegion(tableName, startKey, stopKey, conf, isReadOnly, durability,</span>
<span class="source-line-no">5895</span><span id="line-5895"> wal, families);</span>
<span class="source-line-no">5896</span><span id="line-5896"> }</span>
<span class="source-line-no">5897</span><span id="line-5897"></span>
<span class="source-line-no">5898</span><span id="line-5898"> /**</span>
<span class="source-line-no">5899</span><span id="line-5899"> * Assert that the passed in Cell has expected contents for the specified row, column &amp; timestamp.</span>
<span class="source-line-no">5900</span><span id="line-5900"> */</span>
<span class="source-line-no">5901</span><span id="line-5901"> private void checkOneCell(Cell kv, byte[] cf, int rowIdx, int colIdx, long ts) {</span>
<span class="source-line-no">5902</span><span id="line-5902"> String ctx = "rowIdx=" + rowIdx + "; colIdx=" + colIdx + "; ts=" + ts;</span>
<span class="source-line-no">5903</span><span id="line-5903"> assertEquals("Row mismatch which checking: " + ctx, "row:" + rowIdx,</span>
<span class="source-line-no">5904</span><span id="line-5904"> Bytes.toString(CellUtil.cloneRow(kv)));</span>
<span class="source-line-no">5905</span><span id="line-5905"> assertEquals("ColumnFamily mismatch while checking: " + ctx, Bytes.toString(cf),</span>
<span class="source-line-no">5906</span><span id="line-5906"> Bytes.toString(CellUtil.cloneFamily(kv)));</span>
<span class="source-line-no">5907</span><span id="line-5907"> assertEquals("Column qualifier mismatch while checking: " + ctx, "column:" + colIdx,</span>
<span class="source-line-no">5908</span><span id="line-5908"> Bytes.toString(CellUtil.cloneQualifier(kv)));</span>
<span class="source-line-no">5909</span><span id="line-5909"> assertEquals("Timestamp mismatch while checking: " + ctx, ts, kv.getTimestamp());</span>
<span class="source-line-no">5910</span><span id="line-5910"> assertEquals("Value mismatch while checking: " + ctx, "value-version-" + ts,</span>
<span class="source-line-no">5911</span><span id="line-5911"> Bytes.toString(CellUtil.cloneValue(kv)));</span>
<span class="source-line-no">5912</span><span id="line-5912"> }</span>
<span class="source-line-no">5913</span><span id="line-5913"></span>
<span class="source-line-no">5914</span><span id="line-5914"> @Test</span>
<span class="source-line-no">5915</span><span id="line-5915"> public void testReverseScanner_FromMemStore_SingleCF_Normal() throws IOException {</span>
<span class="source-line-no">5916</span><span id="line-5916"> byte[] rowC = Bytes.toBytes("rowC");</span>
<span class="source-line-no">5917</span><span id="line-5917"> byte[] rowA = Bytes.toBytes("rowA");</span>
<span class="source-line-no">5918</span><span id="line-5918"> byte[] rowB = Bytes.toBytes("rowB");</span>
<span class="source-line-no">5919</span><span id="line-5919"> byte[] cf = Bytes.toBytes("CF");</span>
<span class="source-line-no">5920</span><span id="line-5920"> byte[][] families = { cf };</span>
<span class="source-line-no">5921</span><span id="line-5921"> byte[] col = Bytes.toBytes("C");</span>
<span class="source-line-no">5922</span><span id="line-5922"> long ts = 1;</span>
<span class="source-line-no">5923</span><span id="line-5923"> this.region = initHRegion(tableName, method, families);</span>
<span class="source-line-no">5924</span><span id="line-5924"> KeyValue kv1 = new KeyValue(rowC, cf, col, ts, KeyValue.Type.Put, null);</span>
<span class="source-line-no">5925</span><span id="line-5925"> KeyValue kv11 = new KeyValue(rowC, cf, col, ts + 1, KeyValue.Type.Put, null);</span>
<span class="source-line-no">5926</span><span id="line-5926"> KeyValue kv2 = new KeyValue(rowA, cf, col, ts, KeyValue.Type.Put, null);</span>
<span class="source-line-no">5927</span><span id="line-5927"> KeyValue kv3 = new KeyValue(rowB, cf, col, ts, KeyValue.Type.Put, null);</span>
<span class="source-line-no">5928</span><span id="line-5928"> Put put = null;</span>
<span class="source-line-no">5929</span><span id="line-5929"> put = new Put(rowC);</span>
<span class="source-line-no">5930</span><span id="line-5930"> put.add(kv1);</span>
<span class="source-line-no">5931</span><span id="line-5931"> put.add(kv11);</span>
<span class="source-line-no">5932</span><span id="line-5932"> region.put(put);</span>
<span class="source-line-no">5933</span><span id="line-5933"> put = new Put(rowA);</span>
<span class="source-line-no">5934</span><span id="line-5934"> put.add(kv2);</span>
<span class="source-line-no">5935</span><span id="line-5935"> region.put(put);</span>
<span class="source-line-no">5936</span><span id="line-5936"> put = new Put(rowB);</span>
<span class="source-line-no">5937</span><span id="line-5937"> put.add(kv3);</span>
<span class="source-line-no">5938</span><span id="line-5938"> region.put(put);</span>
<span class="source-line-no">5939</span><span id="line-5939"></span>
<span class="source-line-no">5940</span><span id="line-5940"> Scan scan = new Scan().withStartRow(rowC);</span>
<span class="source-line-no">5941</span><span id="line-5941"> scan.readVersions(5);</span>
<span class="source-line-no">5942</span><span id="line-5942"> scan.setReversed(true);</span>
<span class="source-line-no">5943</span><span id="line-5943"> try (InternalScanner scanner = region.getScanner(scan)) {</span>
<span class="source-line-no">5944</span><span id="line-5944"> List&lt;Cell&gt; currRow = new ArrayList&lt;&gt;();</span>
<span class="source-line-no">5945</span><span id="line-5945"> boolean hasNext = scanner.next(currRow);</span>
<span class="source-line-no">5946</span><span id="line-5946"> assertEquals(2, currRow.size());</span>
<span class="source-line-no">5947</span><span id="line-5947"> assertTrue(Bytes.equals(currRow.get(0).getRowArray(), currRow.get(0).getRowOffset(),</span>
<span class="source-line-no">5948</span><span id="line-5948"> currRow.get(0).getRowLength(), rowC, 0, rowC.length));</span>
<span class="source-line-no">5949</span><span id="line-5949"> assertTrue(hasNext);</span>
<span class="source-line-no">5950</span><span id="line-5950"> currRow.clear();</span>
<span class="source-line-no">5951</span><span id="line-5951"> hasNext = scanner.next(currRow);</span>
<span class="source-line-no">5952</span><span id="line-5952"> assertEquals(1, currRow.size());</span>
<span class="source-line-no">5953</span><span id="line-5953"> assertTrue(Bytes.equals(currRow.get(0).getRowArray(), currRow.get(0).getRowOffset(),</span>
<span class="source-line-no">5954</span><span id="line-5954"> currRow.get(0).getRowLength(), rowB, 0, rowB.length));</span>
<span class="source-line-no">5955</span><span id="line-5955"> assertTrue(hasNext);</span>
<span class="source-line-no">5956</span><span id="line-5956"> currRow.clear();</span>
<span class="source-line-no">5957</span><span id="line-5957"> hasNext = scanner.next(currRow);</span>
<span class="source-line-no">5958</span><span id="line-5958"> assertEquals(1, currRow.size());</span>
<span class="source-line-no">5959</span><span id="line-5959"> assertTrue(Bytes.equals(currRow.get(0).getRowArray(), currRow.get(0).getRowOffset(),</span>
<span class="source-line-no">5960</span><span id="line-5960"> currRow.get(0).getRowLength(), rowA, 0, rowA.length));</span>
<span class="source-line-no">5961</span><span id="line-5961"> assertFalse(hasNext);</span>
<span class="source-line-no">5962</span><span id="line-5962"> }</span>
<span class="source-line-no">5963</span><span id="line-5963"> }</span>
<span class="source-line-no">5964</span><span id="line-5964"></span>
<span class="source-line-no">5965</span><span id="line-5965"> @Test</span>
<span class="source-line-no">5966</span><span id="line-5966"> public void testReverseScanner_FromMemStore_SingleCF_LargerKey() throws IOException {</span>
<span class="source-line-no">5967</span><span id="line-5967"> byte[] rowC = Bytes.toBytes("rowC");</span>
<span class="source-line-no">5968</span><span id="line-5968"> byte[] rowA = Bytes.toBytes("rowA");</span>
<span class="source-line-no">5969</span><span id="line-5969"> byte[] rowB = Bytes.toBytes("rowB");</span>
<span class="source-line-no">5970</span><span id="line-5970"> byte[] rowD = Bytes.toBytes("rowD");</span>
<span class="source-line-no">5971</span><span id="line-5971"> byte[] cf = Bytes.toBytes("CF");</span>
<span class="source-line-no">5972</span><span id="line-5972"> byte[][] families = { cf };</span>
<span class="source-line-no">5973</span><span id="line-5973"> byte[] col = Bytes.toBytes("C");</span>
<span class="source-line-no">5974</span><span id="line-5974"> long ts = 1;</span>
<span class="source-line-no">5975</span><span id="line-5975"> this.region = initHRegion(tableName, method, families);</span>
<span class="source-line-no">5976</span><span id="line-5976"> KeyValue kv1 = new KeyValue(rowC, cf, col, ts, KeyValue.Type.Put, null);</span>
<span class="source-line-no">5977</span><span id="line-5977"> KeyValue kv11 = new KeyValue(rowC, cf, col, ts + 1, KeyValue.Type.Put, null);</span>
<span class="source-line-no">5978</span><span id="line-5978"> KeyValue kv2 = new KeyValue(rowA, cf, col, ts, KeyValue.Type.Put, null);</span>
<span class="source-line-no">5979</span><span id="line-5979"> KeyValue kv3 = new KeyValue(rowB, cf, col, ts, KeyValue.Type.Put, null);</span>
<span class="source-line-no">5980</span><span id="line-5980"> Put put = null;</span>
<span class="source-line-no">5981</span><span id="line-5981"> put = new Put(rowC);</span>
<span class="source-line-no">5982</span><span id="line-5982"> put.add(kv1);</span>
<span class="source-line-no">5983</span><span id="line-5983"> put.add(kv11);</span>
<span class="source-line-no">5984</span><span id="line-5984"> region.put(put);</span>
<span class="source-line-no">5985</span><span id="line-5985"> put = new Put(rowA);</span>
<span class="source-line-no">5986</span><span id="line-5986"> put.add(kv2);</span>
<span class="source-line-no">5987</span><span id="line-5987"> region.put(put);</span>
<span class="source-line-no">5988</span><span id="line-5988"> put = new Put(rowB);</span>
<span class="source-line-no">5989</span><span id="line-5989"> put.add(kv3);</span>
<span class="source-line-no">5990</span><span id="line-5990"> region.put(put);</span>
<span class="source-line-no">5991</span><span id="line-5991"></span>
<span class="source-line-no">5992</span><span id="line-5992"> Scan scan = new Scan().withStartRow(rowD);</span>
<span class="source-line-no">5993</span><span id="line-5993"> List&lt;Cell&gt; currRow = new ArrayList&lt;&gt;();</span>
<span class="source-line-no">5994</span><span id="line-5994"> scan.setReversed(true);</span>
<span class="source-line-no">5995</span><span id="line-5995"> scan.readVersions(5);</span>
<span class="source-line-no">5996</span><span id="line-5996"> try (InternalScanner scanner = region.getScanner(scan)) {</span>
<span class="source-line-no">5997</span><span id="line-5997"> boolean hasNext = scanner.next(currRow);</span>
<span class="source-line-no">5998</span><span id="line-5998"> assertEquals(2, currRow.size());</span>
<span class="source-line-no">5999</span><span id="line-5999"> assertTrue(Bytes.equals(currRow.get(0).getRowArray(), currRow.get(0).getRowOffset(),</span>
<span class="source-line-no">6000</span><span id="line-6000"> currRow.get(0).getRowLength(), rowC, 0, rowC.length));</span>
<span class="source-line-no">6001</span><span id="line-6001"> assertTrue(hasNext);</span>
<span class="source-line-no">6002</span><span id="line-6002"> currRow.clear();</span>
<span class="source-line-no">6003</span><span id="line-6003"> hasNext = scanner.next(currRow);</span>
<span class="source-line-no">6004</span><span id="line-6004"> assertEquals(1, currRow.size());</span>
<span class="source-line-no">6005</span><span id="line-6005"> assertTrue(Bytes.equals(currRow.get(0).getRowArray(), currRow.get(0).getRowOffset(),</span>
<span class="source-line-no">6006</span><span id="line-6006"> currRow.get(0).getRowLength(), rowB, 0, rowB.length));</span>
<span class="source-line-no">6007</span><span id="line-6007"> assertTrue(hasNext);</span>
<span class="source-line-no">6008</span><span id="line-6008"> currRow.clear();</span>
<span class="source-line-no">6009</span><span id="line-6009"> hasNext = scanner.next(currRow);</span>
<span class="source-line-no">6010</span><span id="line-6010"> assertEquals(1, currRow.size());</span>
<span class="source-line-no">6011</span><span id="line-6011"> assertTrue(Bytes.equals(currRow.get(0).getRowArray(), currRow.get(0).getRowOffset(),</span>
<span class="source-line-no">6012</span><span id="line-6012"> currRow.get(0).getRowLength(), rowA, 0, rowA.length));</span>
<span class="source-line-no">6013</span><span id="line-6013"> assertFalse(hasNext);</span>
<span class="source-line-no">6014</span><span id="line-6014"> }</span>
<span class="source-line-no">6015</span><span id="line-6015"> }</span>
<span class="source-line-no">6016</span><span id="line-6016"></span>
<span class="source-line-no">6017</span><span id="line-6017"> @Test</span>
<span class="source-line-no">6018</span><span id="line-6018"> public void testReverseScanner_FromMemStore_SingleCF_FullScan() throws IOException {</span>
<span class="source-line-no">6019</span><span id="line-6019"> byte[] rowC = Bytes.toBytes("rowC");</span>
<span class="source-line-no">6020</span><span id="line-6020"> byte[] rowA = Bytes.toBytes("rowA");</span>
<span class="source-line-no">6021</span><span id="line-6021"> byte[] rowB = Bytes.toBytes("rowB");</span>
<span class="source-line-no">6022</span><span id="line-6022"> byte[] cf = Bytes.toBytes("CF");</span>
<span class="source-line-no">6023</span><span id="line-6023"> byte[][] families = { cf };</span>
<span class="source-line-no">6024</span><span id="line-6024"> byte[] col = Bytes.toBytes("C");</span>
<span class="source-line-no">6025</span><span id="line-6025"> long ts = 1;</span>
<span class="source-line-no">6026</span><span id="line-6026"> this.region = initHRegion(tableName, method, families);</span>
<span class="source-line-no">6027</span><span id="line-6027"> KeyValue kv1 = new KeyValue(rowC, cf, col, ts, KeyValue.Type.Put, null);</span>
<span class="source-line-no">6028</span><span id="line-6028"> KeyValue kv11 = new KeyValue(rowC, cf, col, ts + 1, KeyValue.Type.Put, null);</span>
<span class="source-line-no">6029</span><span id="line-6029"> KeyValue kv2 = new KeyValue(rowA, cf, col, ts, KeyValue.Type.Put, null);</span>
<span class="source-line-no">6030</span><span id="line-6030"> KeyValue kv3 = new KeyValue(rowB, cf, col, ts, KeyValue.Type.Put, null);</span>
<span class="source-line-no">6031</span><span id="line-6031"> Put put = null;</span>
<span class="source-line-no">6032</span><span id="line-6032"> put = new Put(rowC);</span>
<span class="source-line-no">6033</span><span id="line-6033"> put.add(kv1);</span>
<span class="source-line-no">6034</span><span id="line-6034"> put.add(kv11);</span>
<span class="source-line-no">6035</span><span id="line-6035"> region.put(put);</span>
<span class="source-line-no">6036</span><span id="line-6036"> put = new Put(rowA);</span>
<span class="source-line-no">6037</span><span id="line-6037"> put.add(kv2);</span>
<span class="source-line-no">6038</span><span id="line-6038"> region.put(put);</span>
<span class="source-line-no">6039</span><span id="line-6039"> put = new Put(rowB);</span>
<span class="source-line-no">6040</span><span id="line-6040"> put.add(kv3);</span>
<span class="source-line-no">6041</span><span id="line-6041"> region.put(put);</span>
<span class="source-line-no">6042</span><span id="line-6042"> Scan scan = new Scan();</span>
<span class="source-line-no">6043</span><span id="line-6043"> List&lt;Cell&gt; currRow = new ArrayList&lt;&gt;();</span>
<span class="source-line-no">6044</span><span id="line-6044"> scan.setReversed(true);</span>
<span class="source-line-no">6045</span><span id="line-6045"> try (InternalScanner scanner = region.getScanner(scan)) {</span>
<span class="source-line-no">6046</span><span id="line-6046"> boolean hasNext = scanner.next(currRow);</span>
<span class="source-line-no">6047</span><span id="line-6047"> assertEquals(1, currRow.size());</span>
<span class="source-line-no">6048</span><span id="line-6048"> assertTrue(Bytes.equals(currRow.get(0).getRowArray(), currRow.get(0).getRowOffset(),</span>
<span class="source-line-no">6049</span><span id="line-6049"> currRow.get(0).getRowLength(), rowC, 0, rowC.length));</span>
<span class="source-line-no">6050</span><span id="line-6050"> assertTrue(hasNext);</span>
<span class="source-line-no">6051</span><span id="line-6051"> currRow.clear();</span>
<span class="source-line-no">6052</span><span id="line-6052"> hasNext = scanner.next(currRow);</span>
<span class="source-line-no">6053</span><span id="line-6053"> assertEquals(1, currRow.size());</span>
<span class="source-line-no">6054</span><span id="line-6054"> assertTrue(Bytes.equals(currRow.get(0).getRowArray(), currRow.get(0).getRowOffset(),</span>
<span class="source-line-no">6055</span><span id="line-6055"> currRow.get(0).getRowLength(), rowB, 0, rowB.length));</span>
<span class="source-line-no">6056</span><span id="line-6056"> assertTrue(hasNext);</span>
<span class="source-line-no">6057</span><span id="line-6057"> currRow.clear();</span>
<span class="source-line-no">6058</span><span id="line-6058"> hasNext = scanner.next(currRow);</span>
<span class="source-line-no">6059</span><span id="line-6059"> assertEquals(1, currRow.size());</span>
<span class="source-line-no">6060</span><span id="line-6060"> assertTrue(Bytes.equals(currRow.get(0).getRowArray(), currRow.get(0).getRowOffset(),</span>
<span class="source-line-no">6061</span><span id="line-6061"> currRow.get(0).getRowLength(), rowA, 0, rowA.length));</span>
<span class="source-line-no">6062</span><span id="line-6062"> assertFalse(hasNext);</span>
<span class="source-line-no">6063</span><span id="line-6063"> }</span>
<span class="source-line-no">6064</span><span id="line-6064"> }</span>
<span class="source-line-no">6065</span><span id="line-6065"></span>
<span class="source-line-no">6066</span><span id="line-6066"> @Test</span>
<span class="source-line-no">6067</span><span id="line-6067"> public void testReverseScanner_moreRowsMayExistAfter() throws IOException {</span>
<span class="source-line-no">6068</span><span id="line-6068"> // case for "INCLUDE_AND_SEEK_NEXT_ROW &amp; SEEK_NEXT_ROW" endless loop</span>
<span class="source-line-no">6069</span><span id="line-6069"> byte[] rowA = Bytes.toBytes("rowA");</span>
<span class="source-line-no">6070</span><span id="line-6070"> byte[] rowB = Bytes.toBytes("rowB");</span>
<span class="source-line-no">6071</span><span id="line-6071"> byte[] rowC = Bytes.toBytes("rowC");</span>
<span class="source-line-no">6072</span><span id="line-6072"> byte[] rowD = Bytes.toBytes("rowD");</span>
<span class="source-line-no">6073</span><span id="line-6073"> byte[] rowE = Bytes.toBytes("rowE");</span>
<span class="source-line-no">6074</span><span id="line-6074"> byte[] cf = Bytes.toBytes("CF");</span>
<span class="source-line-no">6075</span><span id="line-6075"> byte[][] families = { cf };</span>
<span class="source-line-no">6076</span><span id="line-6076"> byte[] col1 = Bytes.toBytes("col1");</span>
<span class="source-line-no">6077</span><span id="line-6077"> byte[] col2 = Bytes.toBytes("col2");</span>
<span class="source-line-no">6078</span><span id="line-6078"> long ts = 1;</span>
<span class="source-line-no">6079</span><span id="line-6079"> this.region = initHRegion(tableName, method, families);</span>
<span class="source-line-no">6080</span><span id="line-6080"> KeyValue kv1 = new KeyValue(rowA, cf, col1, ts, KeyValue.Type.Put, null);</span>
<span class="source-line-no">6081</span><span id="line-6081"> KeyValue kv2 = new KeyValue(rowB, cf, col1, ts, KeyValue.Type.Put, null);</span>
<span class="source-line-no">6082</span><span id="line-6082"> KeyValue kv3 = new KeyValue(rowC, cf, col1, ts, KeyValue.Type.Put, null);</span>
<span class="source-line-no">6083</span><span id="line-6083"> KeyValue kv4_1 = new KeyValue(rowD, cf, col1, ts, KeyValue.Type.Put, null);</span>
<span class="source-line-no">6084</span><span id="line-6084"> KeyValue kv4_2 = new KeyValue(rowD, cf, col2, ts, KeyValue.Type.Put, null);</span>
<span class="source-line-no">6085</span><span id="line-6085"> KeyValue kv5 = new KeyValue(rowE, cf, col1, ts, KeyValue.Type.Put, null);</span>
<span class="source-line-no">6086</span><span id="line-6086"> Put put = null;</span>
<span class="source-line-no">6087</span><span id="line-6087"> put = new Put(rowA);</span>
<span class="source-line-no">6088</span><span id="line-6088"> put.add(kv1);</span>
<span class="source-line-no">6089</span><span id="line-6089"> region.put(put);</span>
<span class="source-line-no">6090</span><span id="line-6090"> put = new Put(rowB);</span>
<span class="source-line-no">6091</span><span id="line-6091"> put.add(kv2);</span>
<span class="source-line-no">6092</span><span id="line-6092"> region.put(put);</span>
<span class="source-line-no">6093</span><span id="line-6093"> put = new Put(rowC);</span>
<span class="source-line-no">6094</span><span id="line-6094"> put.add(kv3);</span>
<span class="source-line-no">6095</span><span id="line-6095"> region.put(put);</span>
<span class="source-line-no">6096</span><span id="line-6096"> put = new Put(rowD);</span>
<span class="source-line-no">6097</span><span id="line-6097"> put.add(kv4_1);</span>
<span class="source-line-no">6098</span><span id="line-6098"> region.put(put);</span>
<span class="source-line-no">6099</span><span id="line-6099"> put = new Put(rowD);</span>
<span class="source-line-no">6100</span><span id="line-6100"> put.add(kv4_2);</span>
<span class="source-line-no">6101</span><span id="line-6101"> region.put(put);</span>
<span class="source-line-no">6102</span><span id="line-6102"> put = new Put(rowE);</span>
<span class="source-line-no">6103</span><span id="line-6103"> put.add(kv5);</span>
<span class="source-line-no">6104</span><span id="line-6104"> region.put(put);</span>
<span class="source-line-no">6105</span><span id="line-6105"> region.flush(true);</span>
<span class="source-line-no">6106</span><span id="line-6106"> Scan scan = new Scan().withStartRow(rowD).withStopRow(rowA);</span>
<span class="source-line-no">6107</span><span id="line-6107"> scan.addColumn(families[0], col1);</span>
<span class="source-line-no">6108</span><span id="line-6108"> scan.setReversed(true);</span>
<span class="source-line-no">6109</span><span id="line-6109"> List&lt;Cell&gt; currRow = new ArrayList&lt;&gt;();</span>
<span class="source-line-no">6110</span><span id="line-6110"> try (InternalScanner scanner = region.getScanner(scan)) {</span>
<span class="source-line-no">6111</span><span id="line-6111"> boolean hasNext = scanner.next(currRow);</span>
<span class="source-line-no">6112</span><span id="line-6112"> assertEquals(1, currRow.size());</span>
<span class="source-line-no">6113</span><span id="line-6113"> assertTrue(Bytes.equals(currRow.get(0).getRowArray(), currRow.get(0).getRowOffset(),</span>
<span class="source-line-no">6114</span><span id="line-6114"> currRow.get(0).getRowLength(), rowD, 0, rowD.length));</span>
<span class="source-line-no">6115</span><span id="line-6115"> assertTrue(hasNext);</span>
<span class="source-line-no">6116</span><span id="line-6116"> currRow.clear();</span>
<span class="source-line-no">6117</span><span id="line-6117"> hasNext = scanner.next(currRow);</span>
<span class="source-line-no">6118</span><span id="line-6118"> assertEquals(1, currRow.size());</span>
<span class="source-line-no">6119</span><span id="line-6119"> assertTrue(Bytes.equals(currRow.get(0).getRowArray(), currRow.get(0).getRowOffset(),</span>
<span class="source-line-no">6120</span><span id="line-6120"> currRow.get(0).getRowLength(), rowC, 0, rowC.length));</span>
<span class="source-line-no">6121</span><span id="line-6121"> assertTrue(hasNext);</span>
<span class="source-line-no">6122</span><span id="line-6122"> currRow.clear();</span>
<span class="source-line-no">6123</span><span id="line-6123"> hasNext = scanner.next(currRow);</span>
<span class="source-line-no">6124</span><span id="line-6124"> assertEquals(1, currRow.size());</span>
<span class="source-line-no">6125</span><span id="line-6125"> assertTrue(Bytes.equals(currRow.get(0).getRowArray(), currRow.get(0).getRowOffset(),</span>
<span class="source-line-no">6126</span><span id="line-6126"> currRow.get(0).getRowLength(), rowB, 0, rowB.length));</span>
<span class="source-line-no">6127</span><span id="line-6127"> assertFalse(hasNext);</span>
<span class="source-line-no">6128</span><span id="line-6128"> }</span>
<span class="source-line-no">6129</span><span id="line-6129"></span>
<span class="source-line-no">6130</span><span id="line-6130"> scan = new Scan().withStartRow(rowD).withStopRow(rowA);</span>
<span class="source-line-no">6131</span><span id="line-6131"> scan.addColumn(families[0], col2);</span>
<span class="source-line-no">6132</span><span id="line-6132"> scan.setReversed(true);</span>
<span class="source-line-no">6133</span><span id="line-6133"> currRow.clear();</span>
<span class="source-line-no">6134</span><span id="line-6134"> try (InternalScanner scanner = region.getScanner(scan)) {</span>
<span class="source-line-no">6135</span><span id="line-6135"> boolean hasNext = scanner.next(currRow);</span>
<span class="source-line-no">6136</span><span id="line-6136"> assertEquals(1, currRow.size());</span>
<span class="source-line-no">6137</span><span id="line-6137"> assertTrue(Bytes.equals(currRow.get(0).getRowArray(), currRow.get(0).getRowOffset(),</span>
<span class="source-line-no">6138</span><span id="line-6138"> currRow.get(0).getRowLength(), rowD, 0, rowD.length));</span>
<span class="source-line-no">6139</span><span id="line-6139"> assertTrue(hasNext);</span>
<span class="source-line-no">6140</span><span id="line-6140"> }</span>
<span class="source-line-no">6141</span><span id="line-6141"> }</span>
<span class="source-line-no">6142</span><span id="line-6142"></span>
<span class="source-line-no">6143</span><span id="line-6143"> @Test</span>
<span class="source-line-no">6144</span><span id="line-6144"> public void testReverseScanner_smaller_blocksize() throws IOException {</span>
<span class="source-line-no">6145</span><span id="line-6145"> // case to ensure no conflict with HFile index optimization</span>
<span class="source-line-no">6146</span><span id="line-6146"> byte[] rowA = Bytes.toBytes("rowA");</span>
<span class="source-line-no">6147</span><span id="line-6147"> byte[] rowB = Bytes.toBytes("rowB");</span>
<span class="source-line-no">6148</span><span id="line-6148"> byte[] rowC = Bytes.toBytes("rowC");</span>
<span class="source-line-no">6149</span><span id="line-6149"> byte[] rowD = Bytes.toBytes("rowD");</span>
<span class="source-line-no">6150</span><span id="line-6150"> byte[] rowE = Bytes.toBytes("rowE");</span>
<span class="source-line-no">6151</span><span id="line-6151"> byte[] cf = Bytes.toBytes("CF");</span>
<span class="source-line-no">6152</span><span id="line-6152"> byte[][] families = { cf };</span>
<span class="source-line-no">6153</span><span id="line-6153"> byte[] col1 = Bytes.toBytes("col1");</span>
<span class="source-line-no">6154</span><span id="line-6154"> byte[] col2 = Bytes.toBytes("col2");</span>
<span class="source-line-no">6155</span><span id="line-6155"> long ts = 1;</span>
<span class="source-line-no">6156</span><span id="line-6156"> Configuration conf = new Configuration(CONF);</span>
<span class="source-line-no">6157</span><span id="line-6157"> conf.setInt("test.block.size", 1);</span>
<span class="source-line-no">6158</span><span id="line-6158"> this.region = initHRegion(tableName, method, conf, families);</span>
<span class="source-line-no">6159</span><span id="line-6159"> KeyValue kv1 = new KeyValue(rowA, cf, col1, ts, KeyValue.Type.Put, null);</span>
<span class="source-line-no">6160</span><span id="line-6160"> KeyValue kv2 = new KeyValue(rowB, cf, col1, ts, KeyValue.Type.Put, null);</span>
<span class="source-line-no">6161</span><span id="line-6161"> KeyValue kv3 = new KeyValue(rowC, cf, col1, ts, KeyValue.Type.Put, null);</span>
<span class="source-line-no">6162</span><span id="line-6162"> KeyValue kv4_1 = new KeyValue(rowD, cf, col1, ts, KeyValue.Type.Put, null);</span>
<span class="source-line-no">6163</span><span id="line-6163"> KeyValue kv4_2 = new KeyValue(rowD, cf, col2, ts, KeyValue.Type.Put, null);</span>
<span class="source-line-no">6164</span><span id="line-6164"> KeyValue kv5 = new KeyValue(rowE, cf, col1, ts, KeyValue.Type.Put, null);</span>
<span class="source-line-no">6165</span><span id="line-6165"> Put put = null;</span>
<span class="source-line-no">6166</span><span id="line-6166"> put = new Put(rowA);</span>
<span class="source-line-no">6167</span><span id="line-6167"> put.add(kv1);</span>
<span class="source-line-no">6168</span><span id="line-6168"> region.put(put);</span>
<span class="source-line-no">6169</span><span id="line-6169"> put = new Put(rowB);</span>
<span class="source-line-no">6170</span><span id="line-6170"> put.add(kv2);</span>
<span class="source-line-no">6171</span><span id="line-6171"> region.put(put);</span>
<span class="source-line-no">6172</span><span id="line-6172"> put = new Put(rowC);</span>
<span class="source-line-no">6173</span><span id="line-6173"> put.add(kv3);</span>
<span class="source-line-no">6174</span><span id="line-6174"> region.put(put);</span>
<span class="source-line-no">6175</span><span id="line-6175"> put = new Put(rowD);</span>
<span class="source-line-no">6176</span><span id="line-6176"> put.add(kv4_1);</span>
<span class="source-line-no">6177</span><span id="line-6177"> region.put(put);</span>
<span class="source-line-no">6178</span><span id="line-6178"> put = new Put(rowD);</span>
<span class="source-line-no">6179</span><span id="line-6179"> put.add(kv4_2);</span>
<span class="source-line-no">6180</span><span id="line-6180"> region.put(put);</span>
<span class="source-line-no">6181</span><span id="line-6181"> put = new Put(rowE);</span>
<span class="source-line-no">6182</span><span id="line-6182"> put.add(kv5);</span>
<span class="source-line-no">6183</span><span id="line-6183"> region.put(put);</span>
<span class="source-line-no">6184</span><span id="line-6184"> region.flush(true);</span>
<span class="source-line-no">6185</span><span id="line-6185"> Scan scan = new Scan().withStartRow(rowD).withStopRow(rowA);</span>
<span class="source-line-no">6186</span><span id="line-6186"> scan.addColumn(families[0], col1);</span>
<span class="source-line-no">6187</span><span id="line-6187"> scan.setReversed(true);</span>
<span class="source-line-no">6188</span><span id="line-6188"> List&lt;Cell&gt; currRow = new ArrayList&lt;&gt;();</span>
<span class="source-line-no">6189</span><span id="line-6189"> try (InternalScanner scanner = region.getScanner(scan)) {</span>
<span class="source-line-no">6190</span><span id="line-6190"> boolean hasNext = scanner.next(currRow);</span>
<span class="source-line-no">6191</span><span id="line-6191"> assertEquals(1, currRow.size());</span>
<span class="source-line-no">6192</span><span id="line-6192"> assertTrue(Bytes.equals(currRow.get(0).getRowArray(), currRow.get(0).getRowOffset(),</span>
<span class="source-line-no">6193</span><span id="line-6193"> currRow.get(0).getRowLength(), rowD, 0, rowD.length));</span>
<span class="source-line-no">6194</span><span id="line-6194"> assertTrue(hasNext);</span>
<span class="source-line-no">6195</span><span id="line-6195"> currRow.clear();</span>
<span class="source-line-no">6196</span><span id="line-6196"> hasNext = scanner.next(currRow);</span>
<span class="source-line-no">6197</span><span id="line-6197"> assertEquals(1, currRow.size());</span>
<span class="source-line-no">6198</span><span id="line-6198"> assertTrue(Bytes.equals(currRow.get(0).getRowArray(), currRow.get(0).getRowOffset(),</span>
<span class="source-line-no">6199</span><span id="line-6199"> currRow.get(0).getRowLength(), rowC, 0, rowC.length));</span>
<span class="source-line-no">6200</span><span id="line-6200"> assertTrue(hasNext);</span>
<span class="source-line-no">6201</span><span id="line-6201"> currRow.clear();</span>
<span class="source-line-no">6202</span><span id="line-6202"> hasNext = scanner.next(currRow);</span>
<span class="source-line-no">6203</span><span id="line-6203"> assertEquals(1, currRow.size());</span>
<span class="source-line-no">6204</span><span id="line-6204"> assertTrue(Bytes.equals(currRow.get(0).getRowArray(), currRow.get(0).getRowOffset(),</span>
<span class="source-line-no">6205</span><span id="line-6205"> currRow.get(0).getRowLength(), rowB, 0, rowB.length));</span>
<span class="source-line-no">6206</span><span id="line-6206"> assertFalse(hasNext);</span>
<span class="source-line-no">6207</span><span id="line-6207"> }</span>
<span class="source-line-no">6208</span><span id="line-6208"></span>
<span class="source-line-no">6209</span><span id="line-6209"> scan = new Scan().withStartRow(rowD).withStopRow(rowA);</span>
<span class="source-line-no">6210</span><span id="line-6210"> scan.addColumn(families[0], col2);</span>
<span class="source-line-no">6211</span><span id="line-6211"> scan.setReversed(true);</span>
<span class="source-line-no">6212</span><span id="line-6212"> currRow.clear();</span>
<span class="source-line-no">6213</span><span id="line-6213"> try (InternalScanner scanner = region.getScanner(scan)) {</span>
<span class="source-line-no">6214</span><span id="line-6214"> boolean hasNext = scanner.next(currRow);</span>
<span class="source-line-no">6215</span><span id="line-6215"> assertEquals(1, currRow.size());</span>
<span class="source-line-no">6216</span><span id="line-6216"> assertTrue(Bytes.equals(currRow.get(0).getRowArray(), currRow.get(0).getRowOffset(),</span>
<span class="source-line-no">6217</span><span id="line-6217"> currRow.get(0).getRowLength(), rowD, 0, rowD.length));</span>
<span class="source-line-no">6218</span><span id="line-6218"> assertTrue(hasNext);</span>
<span class="source-line-no">6219</span><span id="line-6219"> }</span>
<span class="source-line-no">6220</span><span id="line-6220"> }</span>
<span class="source-line-no">6221</span><span id="line-6221"></span>
<span class="source-line-no">6222</span><span id="line-6222"> @Test</span>
<span class="source-line-no">6223</span><span id="line-6223"> public void testReverseScanner_FromMemStoreAndHFiles_MultiCFs1() throws IOException {</span>
<span class="source-line-no">6224</span><span id="line-6224"> byte[] row0 = Bytes.toBytes("row0"); // 1 kv</span>
<span class="source-line-no">6225</span><span id="line-6225"> byte[] row1 = Bytes.toBytes("row1"); // 2 kv</span>
<span class="source-line-no">6226</span><span id="line-6226"> byte[] row2 = Bytes.toBytes("row2"); // 4 kv</span>
<span class="source-line-no">6227</span><span id="line-6227"> byte[] row3 = Bytes.toBytes("row3"); // 2 kv</span>
<span class="source-line-no">6228</span><span id="line-6228"> byte[] row4 = Bytes.toBytes("row4"); // 5 kv</span>
<span class="source-line-no">6229</span><span id="line-6229"> byte[] row5 = Bytes.toBytes("row5"); // 2 kv</span>
<span class="source-line-no">6230</span><span id="line-6230"> byte[] cf1 = Bytes.toBytes("CF1");</span>
<span class="source-line-no">6231</span><span id="line-6231"> byte[] cf2 = Bytes.toBytes("CF2");</span>
<span class="source-line-no">6232</span><span id="line-6232"> byte[] cf3 = Bytes.toBytes("CF3");</span>
<span class="source-line-no">6233</span><span id="line-6233"> byte[][] families = { cf1, cf2, cf3 };</span>
<span class="source-line-no">6234</span><span id="line-6234"> byte[] col = Bytes.toBytes("C");</span>
<span class="source-line-no">6235</span><span id="line-6235"> long ts = 1;</span>
<span class="source-line-no">6236</span><span id="line-6236"> Configuration conf = new Configuration(CONF);</span>
<span class="source-line-no">6237</span><span id="line-6237"> // disable compactions in this test.</span>
<span class="source-line-no">6238</span><span id="line-6238"> conf.setInt("hbase.hstore.compactionThreshold", 10000);</span>
<span class="source-line-no">6239</span><span id="line-6239"> this.region = initHRegion(tableName, method, conf, families);</span>
<span class="source-line-no">6240</span><span id="line-6240"> // kv naming style: kv(row number) totalKvCountInThisRow seq no</span>
<span class="source-line-no">6241</span><span id="line-6241"> KeyValue kv0_1_1 = new KeyValue(row0, cf1, col, ts, KeyValue.Type.Put, null);</span>
<span class="source-line-no">6242</span><span id="line-6242"> KeyValue kv1_2_1 = new KeyValue(row1, cf2, col, ts, KeyValue.Type.Put, null);</span>
<span class="source-line-no">6243</span><span id="line-6243"> KeyValue kv1_2_2 = new KeyValue(row1, cf1, col, ts + 1, KeyValue.Type.Put, null);</span>
<span class="source-line-no">6244</span><span id="line-6244"> KeyValue kv2_4_1 = new KeyValue(row2, cf2, col, ts, KeyValue.Type.Put, null);</span>
<span class="source-line-no">6245</span><span id="line-6245"> KeyValue kv2_4_2 = new KeyValue(row2, cf1, col, ts, KeyValue.Type.Put, null);</span>
<span class="source-line-no">6246</span><span id="line-6246"> KeyValue kv2_4_3 = new KeyValue(row2, cf3, col, ts, KeyValue.Type.Put, null);</span>
<span class="source-line-no">6247</span><span id="line-6247"> KeyValue kv2_4_4 = new KeyValue(row2, cf1, col, ts + 4, KeyValue.Type.Put, null);</span>
<span class="source-line-no">6248</span><span id="line-6248"> KeyValue kv3_2_1 = new KeyValue(row3, cf2, col, ts, KeyValue.Type.Put, null);</span>
<span class="source-line-no">6249</span><span id="line-6249"> KeyValue kv3_2_2 = new KeyValue(row3, cf1, col, ts + 4, KeyValue.Type.Put, null);</span>
<span class="source-line-no">6250</span><span id="line-6250"> KeyValue kv4_5_1 = new KeyValue(row4, cf1, col, ts, KeyValue.Type.Put, null);</span>
<span class="source-line-no">6251</span><span id="line-6251"> KeyValue kv4_5_2 = new KeyValue(row4, cf3, col, ts, KeyValue.Type.Put, null);</span>
<span class="source-line-no">6252</span><span id="line-6252"> KeyValue kv4_5_3 = new KeyValue(row4, cf3, col, ts + 5, KeyValue.Type.Put, null);</span>
<span class="source-line-no">6253</span><span id="line-6253"> KeyValue kv4_5_4 = new KeyValue(row4, cf2, col, ts, KeyValue.Type.Put, null);</span>
<span class="source-line-no">6254</span><span id="line-6254"> KeyValue kv4_5_5 = new KeyValue(row4, cf1, col, ts + 3, KeyValue.Type.Put, null);</span>
<span class="source-line-no">6255</span><span id="line-6255"> KeyValue kv5_2_1 = new KeyValue(row5, cf2, col, ts, KeyValue.Type.Put, null);</span>
<span class="source-line-no">6256</span><span id="line-6256"> KeyValue kv5_2_2 = new KeyValue(row5, cf3, col, ts, KeyValue.Type.Put, null);</span>
<span class="source-line-no">6257</span><span id="line-6257"> // hfiles(cf1/cf2) :"row1"(1 kv) / "row2"(1 kv) / "row4"(2 kv)</span>
<span class="source-line-no">6258</span><span id="line-6258"> Put put = null;</span>
<span class="source-line-no">6259</span><span id="line-6259"> put = new Put(row1);</span>
<span class="source-line-no">6260</span><span id="line-6260"> put.add(kv1_2_1);</span>
<span class="source-line-no">6261</span><span id="line-6261"> region.put(put);</span>
<span class="source-line-no">6262</span><span id="line-6262"> put = new Put(row2);</span>
<span class="source-line-no">6263</span><span id="line-6263"> put.add(kv2_4_1);</span>
<span class="source-line-no">6264</span><span id="line-6264"> region.put(put);</span>
<span class="source-line-no">6265</span><span id="line-6265"> put = new Put(row4);</span>
<span class="source-line-no">6266</span><span id="line-6266"> put.add(kv4_5_4);</span>
<span class="source-line-no">6267</span><span id="line-6267"> put.add(kv4_5_5);</span>
<span class="source-line-no">6268</span><span id="line-6268"> region.put(put);</span>
<span class="source-line-no">6269</span><span id="line-6269"> region.flush(true);</span>
<span class="source-line-no">6270</span><span id="line-6270"> // hfiles(cf1/cf3) : "row1" (1 kvs) / "row2" (1 kv) / "row4" (2 kv)</span>
<span class="source-line-no">6271</span><span id="line-6271"> put = new Put(row4);</span>
<span class="source-line-no">6272</span><span id="line-6272"> put.add(kv4_5_1);</span>
<span class="source-line-no">6273</span><span id="line-6273"> put.add(kv4_5_3);</span>
<span class="source-line-no">6274</span><span id="line-6274"> region.put(put);</span>
<span class="source-line-no">6275</span><span id="line-6275"> put = new Put(row1);</span>
<span class="source-line-no">6276</span><span id="line-6276"> put.add(kv1_2_2);</span>
<span class="source-line-no">6277</span><span id="line-6277"> region.put(put);</span>
<span class="source-line-no">6278</span><span id="line-6278"> put = new Put(row2);</span>
<span class="source-line-no">6279</span><span id="line-6279"> put.add(kv2_4_4);</span>
<span class="source-line-no">6280</span><span id="line-6280"> region.put(put);</span>
<span class="source-line-no">6281</span><span id="line-6281"> region.flush(true);</span>
<span class="source-line-no">6282</span><span id="line-6282"> // hfiles(cf1/cf3) : "row2"(2 kv) / "row3"(1 kvs) / "row4" (1 kv)</span>
<span class="source-line-no">6283</span><span id="line-6283"> put = new Put(row4);</span>
<span class="source-line-no">6284</span><span id="line-6284"> put.add(kv4_5_2);</span>
<span class="source-line-no">6285</span><span id="line-6285"> region.put(put);</span>
<span class="source-line-no">6286</span><span id="line-6286"> put = new Put(row2);</span>
<span class="source-line-no">6287</span><span id="line-6287"> put.add(kv2_4_2);</span>
<span class="source-line-no">6288</span><span id="line-6288"> put.add(kv2_4_3);</span>
<span class="source-line-no">6289</span><span id="line-6289"> region.put(put);</span>
<span class="source-line-no">6290</span><span id="line-6290"> put = new Put(row3);</span>
<span class="source-line-no">6291</span><span id="line-6291"> put.add(kv3_2_2);</span>
<span class="source-line-no">6292</span><span id="line-6292"> region.put(put);</span>
<span class="source-line-no">6293</span><span id="line-6293"> region.flush(true);</span>
<span class="source-line-no">6294</span><span id="line-6294"> // memstore(cf1/cf2/cf3) : "row0" (1 kvs) / "row3" ( 1 kv) / "row5" (max)</span>
<span class="source-line-no">6295</span><span id="line-6295"> // ( 2 kv)</span>
<span class="source-line-no">6296</span><span id="line-6296"> put = new Put(row0);</span>
<span class="source-line-no">6297</span><span id="line-6297"> put.add(kv0_1_1);</span>
<span class="source-line-no">6298</span><span id="line-6298"> region.put(put);</span>
<span class="source-line-no">6299</span><span id="line-6299"> put = new Put(row3);</span>
<span class="source-line-no">6300</span><span id="line-6300"> put.add(kv3_2_1);</span>
<span class="source-line-no">6301</span><span id="line-6301"> region.put(put);</span>
<span class="source-line-no">6302</span><span id="line-6302"> put = new Put(row5);</span>
<span class="source-line-no">6303</span><span id="line-6303"> put.add(kv5_2_1);</span>
<span class="source-line-no">6304</span><span id="line-6304"> put.add(kv5_2_2);</span>
<span class="source-line-no">6305</span><span id="line-6305"> region.put(put);</span>
<span class="source-line-no">6306</span><span id="line-6306"> // scan range = ["row4", min), skip the max "row5"</span>
<span class="source-line-no">6307</span><span id="line-6307"> Scan scan = new Scan().withStartRow(row4);</span>
<span class="source-line-no">6308</span><span id="line-6308"> scan.readVersions(5);</span>
<span class="source-line-no">6309</span><span id="line-6309"> scan.setBatch(3);</span>
<span class="source-line-no">6310</span><span id="line-6310"> scan.setReversed(true);</span>
<span class="source-line-no">6311</span><span id="line-6311"> try (InternalScanner scanner = region.getScanner(scan)) {</span>
<span class="source-line-no">6312</span><span id="line-6312"> List&lt;Cell&gt; currRow = new ArrayList&lt;&gt;();</span>
<span class="source-line-no">6313</span><span id="line-6313"> boolean hasNext = false;</span>
<span class="source-line-no">6314</span><span id="line-6314"> // 1. scan out "row4" (5 kvs), "row5" can't be scanned out since not</span>
<span class="source-line-no">6315</span><span id="line-6315"> // included in scan range</span>
<span class="source-line-no">6316</span><span id="line-6316"> // "row4" takes 2 next() calls since batch=3</span>
<span class="source-line-no">6317</span><span id="line-6317"> hasNext = scanner.next(currRow);</span>
<span class="source-line-no">6318</span><span id="line-6318"> assertEquals(3, currRow.size());</span>
<span class="source-line-no">6319</span><span id="line-6319"> assertTrue(Bytes.equals(currRow.get(0).getRowArray(), currRow.get(0).getRowOffset(),</span>
<span class="source-line-no">6320</span><span id="line-6320"> currRow.get(0).getRowLength(), row4, 0, row4.length));</span>
<span class="source-line-no">6321</span><span id="line-6321"> assertTrue(hasNext);</span>
<span class="source-line-no">6322</span><span id="line-6322"> currRow.clear();</span>
<span class="source-line-no">6323</span><span id="line-6323"> hasNext = scanner.next(currRow);</span>
<span class="source-line-no">6324</span><span id="line-6324"> assertEquals(2, currRow.size());</span>
<span class="source-line-no">6325</span><span id="line-6325"> assertTrue(Bytes.equals(currRow.get(0).getRowArray(), currRow.get(0).getRowOffset(),</span>
<span class="source-line-no">6326</span><span id="line-6326"> currRow.get(0).getRowLength(), row4, 0, row4.length));</span>
<span class="source-line-no">6327</span><span id="line-6327"> assertTrue(hasNext);</span>
<span class="source-line-no">6328</span><span id="line-6328"> // 2. scan out "row3" (2 kv)</span>
<span class="source-line-no">6329</span><span id="line-6329"> currRow.clear();</span>
<span class="source-line-no">6330</span><span id="line-6330"> hasNext = scanner.next(currRow);</span>
<span class="source-line-no">6331</span><span id="line-6331"> assertEquals(2, currRow.size());</span>
<span class="source-line-no">6332</span><span id="line-6332"> assertTrue(Bytes.equals(currRow.get(0).getRowArray(), currRow.get(0).getRowOffset(),</span>
<span class="source-line-no">6333</span><span id="line-6333"> currRow.get(0).getRowLength(), row3, 0, row3.length));</span>
<span class="source-line-no">6334</span><span id="line-6334"> assertTrue(hasNext);</span>
<span class="source-line-no">6335</span><span id="line-6335"> // 3. scan out "row2" (4 kvs)</span>
<span class="source-line-no">6336</span><span id="line-6336"> // "row2" takes 2 next() calls since batch=3</span>
<span class="source-line-no">6337</span><span id="line-6337"> currRow.clear();</span>
<span class="source-line-no">6338</span><span id="line-6338"> hasNext = scanner.next(currRow);</span>
<span class="source-line-no">6339</span><span id="line-6339"> assertEquals(3, currRow.size());</span>
<span class="source-line-no">6340</span><span id="line-6340"> assertTrue(Bytes.equals(currRow.get(0).getRowArray(), currRow.get(0).getRowOffset(),</span>
<span class="source-line-no">6341</span><span id="line-6341"> currRow.get(0).getRowLength(), row2, 0, row2.length));</span>
<span class="source-line-no">6342</span><span id="line-6342"> assertTrue(hasNext);</span>
<span class="source-line-no">6343</span><span id="line-6343"> currRow.clear();</span>
<span class="source-line-no">6344</span><span id="line-6344"> hasNext = scanner.next(currRow);</span>
<span class="source-line-no">6345</span><span id="line-6345"> assertEquals(1, currRow.size());</span>
<span class="source-line-no">6346</span><span id="line-6346"> assertTrue(Bytes.equals(currRow.get(0).getRowArray(), currRow.get(0).getRowOffset(),</span>
<span class="source-line-no">6347</span><span id="line-6347"> currRow.get(0).getRowLength(), row2, 0, row2.length));</span>
<span class="source-line-no">6348</span><span id="line-6348"> assertTrue(hasNext);</span>
<span class="source-line-no">6349</span><span id="line-6349"> // 4. scan out "row1" (2 kv)</span>
<span class="source-line-no">6350</span><span id="line-6350"> currRow.clear();</span>
<span class="source-line-no">6351</span><span id="line-6351"> hasNext = scanner.next(currRow);</span>
<span class="source-line-no">6352</span><span id="line-6352"> assertEquals(2, currRow.size());</span>
<span class="source-line-no">6353</span><span id="line-6353"> assertTrue(Bytes.equals(currRow.get(0).getRowArray(), currRow.get(0).getRowOffset(),</span>
<span class="source-line-no">6354</span><span id="line-6354"> currRow.get(0).getRowLength(), row1, 0, row1.length));</span>
<span class="source-line-no">6355</span><span id="line-6355"> assertTrue(hasNext);</span>
<span class="source-line-no">6356</span><span id="line-6356"> // 5. scan out "row0" (1 kv)</span>
<span class="source-line-no">6357</span><span id="line-6357"> currRow.clear();</span>
<span class="source-line-no">6358</span><span id="line-6358"> hasNext = scanner.next(currRow);</span>
<span class="source-line-no">6359</span><span id="line-6359"> assertEquals(1, currRow.size());</span>
<span class="source-line-no">6360</span><span id="line-6360"> assertTrue(Bytes.equals(currRow.get(0).getRowArray(), currRow.get(0).getRowOffset(),</span>
<span class="source-line-no">6361</span><span id="line-6361"> currRow.get(0).getRowLength(), row0, 0, row0.length));</span>
<span class="source-line-no">6362</span><span id="line-6362"> assertFalse(hasNext);</span>
<span class="source-line-no">6363</span><span id="line-6363"> }</span>
<span class="source-line-no">6364</span><span id="line-6364"> }</span>
<span class="source-line-no">6365</span><span id="line-6365"></span>
<span class="source-line-no">6366</span><span id="line-6366"> @Test</span>
<span class="source-line-no">6367</span><span id="line-6367"> public void testReverseScanner_FromMemStoreAndHFiles_MultiCFs2() throws IOException {</span>
<span class="source-line-no">6368</span><span id="line-6368"> byte[] row1 = Bytes.toBytes("row1");</span>
<span class="source-line-no">6369</span><span id="line-6369"> byte[] row2 = Bytes.toBytes("row2");</span>
<span class="source-line-no">6370</span><span id="line-6370"> byte[] row3 = Bytes.toBytes("row3");</span>
<span class="source-line-no">6371</span><span id="line-6371"> byte[] row4 = Bytes.toBytes("row4");</span>
<span class="source-line-no">6372</span><span id="line-6372"> byte[] cf1 = Bytes.toBytes("CF1");</span>
<span class="source-line-no">6373</span><span id="line-6373"> byte[] cf2 = Bytes.toBytes("CF2");</span>
<span class="source-line-no">6374</span><span id="line-6374"> byte[] cf3 = Bytes.toBytes("CF3");</span>
<span class="source-line-no">6375</span><span id="line-6375"> byte[] cf4 = Bytes.toBytes("CF4");</span>
<span class="source-line-no">6376</span><span id="line-6376"> byte[][] families = { cf1, cf2, cf3, cf4 };</span>
<span class="source-line-no">6377</span><span id="line-6377"> byte[] col = Bytes.toBytes("C");</span>
<span class="source-line-no">6378</span><span id="line-6378"> long ts = 1;</span>
<span class="source-line-no">6379</span><span id="line-6379"> Configuration conf = new Configuration(CONF);</span>
<span class="source-line-no">6380</span><span id="line-6380"> // disable compactions in this test.</span>
<span class="source-line-no">6381</span><span id="line-6381"> conf.setInt("hbase.hstore.compactionThreshold", 10000);</span>
<span class="source-line-no">6382</span><span id="line-6382"> this.region = initHRegion(tableName, method, conf, families);</span>
<span class="source-line-no">6383</span><span id="line-6383"> KeyValue kv1 = new KeyValue(row1, cf1, col, ts, KeyValue.Type.Put, null);</span>
<span class="source-line-no">6384</span><span id="line-6384"> KeyValue kv2 = new KeyValue(row2, cf2, col, ts, KeyValue.Type.Put, null);</span>
<span class="source-line-no">6385</span><span id="line-6385"> KeyValue kv3 = new KeyValue(row3, cf3, col, ts, KeyValue.Type.Put, null);</span>
<span class="source-line-no">6386</span><span id="line-6386"> KeyValue kv4 = new KeyValue(row4, cf4, col, ts, KeyValue.Type.Put, null);</span>
<span class="source-line-no">6387</span><span id="line-6387"> // storefile1</span>
<span class="source-line-no">6388</span><span id="line-6388"> Put put = new Put(row1);</span>
<span class="source-line-no">6389</span><span id="line-6389"> put.add(kv1);</span>
<span class="source-line-no">6390</span><span id="line-6390"> region.put(put);</span>
<span class="source-line-no">6391</span><span id="line-6391"> region.flush(true);</span>
<span class="source-line-no">6392</span><span id="line-6392"> // storefile2</span>
<span class="source-line-no">6393</span><span id="line-6393"> put = new Put(row2);</span>
<span class="source-line-no">6394</span><span id="line-6394"> put.add(kv2);</span>
<span class="source-line-no">6395</span><span id="line-6395"> region.put(put);</span>
<span class="source-line-no">6396</span><span id="line-6396"> region.flush(true);</span>
<span class="source-line-no">6397</span><span id="line-6397"> // storefile3</span>
<span class="source-line-no">6398</span><span id="line-6398"> put = new Put(row3);</span>
<span class="source-line-no">6399</span><span id="line-6399"> put.add(kv3);</span>
<span class="source-line-no">6400</span><span id="line-6400"> region.put(put);</span>
<span class="source-line-no">6401</span><span id="line-6401"> region.flush(true);</span>
<span class="source-line-no">6402</span><span id="line-6402"> // memstore</span>
<span class="source-line-no">6403</span><span id="line-6403"> put = new Put(row4);</span>
<span class="source-line-no">6404</span><span id="line-6404"> put.add(kv4);</span>
<span class="source-line-no">6405</span><span id="line-6405"> region.put(put);</span>
<span class="source-line-no">6406</span><span id="line-6406"> // scan range = ["row4", min)</span>
<span class="source-line-no">6407</span><span id="line-6407"> Scan scan = new Scan().withStartRow(row4);</span>
<span class="source-line-no">6408</span><span id="line-6408"> scan.setReversed(true);</span>
<span class="source-line-no">6409</span><span id="line-6409"> scan.setBatch(10);</span>
<span class="source-line-no">6410</span><span id="line-6410"> try (InternalScanner scanner = region.getScanner(scan)) {</span>
<span class="source-line-no">6411</span><span id="line-6411"> List&lt;Cell&gt; currRow = new ArrayList&lt;&gt;();</span>
<span class="source-line-no">6412</span><span id="line-6412"> boolean hasNext = scanner.next(currRow);</span>
<span class="source-line-no">6413</span><span id="line-6413"> assertEquals(1, currRow.size());</span>
<span class="source-line-no">6414</span><span id="line-6414"> assertTrue(Bytes.equals(currRow.get(0).getRowArray(), currRow.get(0).getRowOffset(),</span>
<span class="source-line-no">6415</span><span id="line-6415"> currRow.get(0).getRowLength(), row4, 0, row4.length));</span>
<span class="source-line-no">6416</span><span id="line-6416"> assertTrue(hasNext);</span>
<span class="source-line-no">6417</span><span id="line-6417"> currRow.clear();</span>
<span class="source-line-no">6418</span><span id="line-6418"> hasNext = scanner.next(currRow);</span>
<span class="source-line-no">6419</span><span id="line-6419"> assertEquals(1, currRow.size());</span>
<span class="source-line-no">6420</span><span id="line-6420"> assertTrue(Bytes.equals(currRow.get(0).getRowArray(), currRow.get(0).getRowOffset(),</span>
<span class="source-line-no">6421</span><span id="line-6421"> currRow.get(0).getRowLength(), row3, 0, row3.length));</span>
<span class="source-line-no">6422</span><span id="line-6422"> assertTrue(hasNext);</span>
<span class="source-line-no">6423</span><span id="line-6423"> currRow.clear();</span>
<span class="source-line-no">6424</span><span id="line-6424"> hasNext = scanner.next(currRow);</span>
<span class="source-line-no">6425</span><span id="line-6425"> assertEquals(1, currRow.size());</span>
<span class="source-line-no">6426</span><span id="line-6426"> assertTrue(Bytes.equals(currRow.get(0).getRowArray(), currRow.get(0).getRowOffset(),</span>
<span class="source-line-no">6427</span><span id="line-6427"> currRow.get(0).getRowLength(), row2, 0, row2.length));</span>
<span class="source-line-no">6428</span><span id="line-6428"> assertTrue(hasNext);</span>
<span class="source-line-no">6429</span><span id="line-6429"> currRow.clear();</span>
<span class="source-line-no">6430</span><span id="line-6430"> hasNext = scanner.next(currRow);</span>
<span class="source-line-no">6431</span><span id="line-6431"> assertEquals(1, currRow.size());</span>
<span class="source-line-no">6432</span><span id="line-6432"> assertTrue(Bytes.equals(currRow.get(0).getRowArray(), currRow.get(0).getRowOffset(),</span>
<span class="source-line-no">6433</span><span id="line-6433"> currRow.get(0).getRowLength(), row1, 0, row1.length));</span>
<span class="source-line-no">6434</span><span id="line-6434"> assertFalse(hasNext);</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"></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 for HBASE-14497: Reverse Scan threw StackOverflow caused by readPt checking</span>
<span class="source-line-no">6440</span><span id="line-6440"> */</span>
<span class="source-line-no">6441</span><span id="line-6441"> @Test</span>
<span class="source-line-no">6442</span><span id="line-6442"> public void testReverseScanner_StackOverflow() throws IOException {</span>
<span class="source-line-no">6443</span><span id="line-6443"> byte[] cf1 = Bytes.toBytes("CF1");</span>
<span class="source-line-no">6444</span><span id="line-6444"> byte[][] families = { cf1 };</span>
<span class="source-line-no">6445</span><span id="line-6445"> byte[] col = Bytes.toBytes("C");</span>
<span class="source-line-no">6446</span><span id="line-6446"> Configuration conf = new Configuration(CONF);</span>
<span class="source-line-no">6447</span><span id="line-6447"> this.region = initHRegion(tableName, method, conf, families);</span>
<span class="source-line-no">6448</span><span id="line-6448"> // setup with one storefile and one memstore, to create scanner and get an earlier readPt</span>
<span class="source-line-no">6449</span><span id="line-6449"> Put put = new Put(Bytes.toBytes("19998"));</span>
<span class="source-line-no">6450</span><span id="line-6450"> put.addColumn(cf1, col, Bytes.toBytes("val"));</span>
<span class="source-line-no">6451</span><span id="line-6451"> region.put(put);</span>
<span class="source-line-no">6452</span><span id="line-6452"> region.flushcache(true, true, FlushLifeCycleTracker.DUMMY);</span>
<span class="source-line-no">6453</span><span id="line-6453"> Put put2 = new Put(Bytes.toBytes("19997"));</span>
<span class="source-line-no">6454</span><span id="line-6454"> put2.addColumn(cf1, col, Bytes.toBytes("val"));</span>
<span class="source-line-no">6455</span><span id="line-6455"> region.put(put2);</span>
<span class="source-line-no">6456</span><span id="line-6456"></span>
<span class="source-line-no">6457</span><span id="line-6457"> Scan scan = new Scan().withStartRow(Bytes.toBytes("19998"));</span>
<span class="source-line-no">6458</span><span id="line-6458"> scan.setReversed(true);</span>
<span class="source-line-no">6459</span><span id="line-6459"> try (InternalScanner scanner = region.getScanner(scan)) {</span>
<span class="source-line-no">6460</span><span id="line-6460"> // create one storefile contains many rows will be skipped</span>
<span class="source-line-no">6461</span><span id="line-6461"> // to check StoreFileScanner.seekToPreviousRow</span>
<span class="source-line-no">6462</span><span id="line-6462"> for (int i = 10000; i &lt; 20000; i++) {</span>
<span class="source-line-no">6463</span><span id="line-6463"> Put p = new Put(Bytes.toBytes("" + i));</span>
<span class="source-line-no">6464</span><span id="line-6464"> p.addColumn(cf1, col, Bytes.toBytes("" + i));</span>
<span class="source-line-no">6465</span><span id="line-6465"> region.put(p);</span>
<span class="source-line-no">6466</span><span id="line-6466"> }</span>
<span class="source-line-no">6467</span><span id="line-6467"> region.flushcache(true, true, FlushLifeCycleTracker.DUMMY);</span>
<span class="source-line-no">6468</span><span id="line-6468"></span>
<span class="source-line-no">6469</span><span id="line-6469"> // create one memstore contains many rows will be skipped</span>
<span class="source-line-no">6470</span><span id="line-6470"> // to check MemStoreScanner.seekToPreviousRow</span>
<span class="source-line-no">6471</span><span id="line-6471"> for (int i = 10000; i &lt; 20000; i++) {</span>
<span class="source-line-no">6472</span><span id="line-6472"> Put p = new Put(Bytes.toBytes("" + i));</span>
<span class="source-line-no">6473</span><span id="line-6473"> p.addColumn(cf1, col, Bytes.toBytes("" + i));</span>
<span class="source-line-no">6474</span><span id="line-6474"> region.put(p);</span>
<span class="source-line-no">6475</span><span id="line-6475"> }</span>
<span class="source-line-no">6476</span><span id="line-6476"></span>
<span class="source-line-no">6477</span><span id="line-6477"> List&lt;Cell&gt; currRow = new ArrayList&lt;&gt;();</span>
<span class="source-line-no">6478</span><span id="line-6478"> boolean hasNext;</span>
<span class="source-line-no">6479</span><span id="line-6479"> do {</span>
<span class="source-line-no">6480</span><span id="line-6480"> hasNext = scanner.next(currRow);</span>
<span class="source-line-no">6481</span><span id="line-6481"> } while (hasNext);</span>
<span class="source-line-no">6482</span><span id="line-6482"> assertEquals(2, currRow.size());</span>
<span class="source-line-no">6483</span><span id="line-6483"> assertEquals("19998", Bytes.toString(currRow.get(0).getRowArray(),</span>
<span class="source-line-no">6484</span><span id="line-6484"> currRow.get(0).getRowOffset(), currRow.get(0).getRowLength()));</span>
<span class="source-line-no">6485</span><span id="line-6485"> assertEquals("19997", Bytes.toString(currRow.get(1).getRowArray(),</span>
<span class="source-line-no">6486</span><span id="line-6486"> currRow.get(1).getRowOffset(), currRow.get(1).getRowLength()));</span>
<span class="source-line-no">6487</span><span id="line-6487"> }</span>
<span class="source-line-no">6488</span><span id="line-6488"> }</span>
<span class="source-line-no">6489</span><span id="line-6489"></span>
<span class="source-line-no">6490</span><span id="line-6490"> @Test</span>
<span class="source-line-no">6491</span><span id="line-6491"> public void testReverseScanShouldNotScanMemstoreIfReadPtLesser() throws Exception {</span>
<span class="source-line-no">6492</span><span id="line-6492"> byte[] cf1 = Bytes.toBytes("CF1");</span>
<span class="source-line-no">6493</span><span id="line-6493"> byte[][] families = { cf1 };</span>
<span class="source-line-no">6494</span><span id="line-6494"> byte[] col = Bytes.toBytes("C");</span>
<span class="source-line-no">6495</span><span id="line-6495"> this.region = initHRegion(tableName, method, CONF, families);</span>
<span class="source-line-no">6496</span><span id="line-6496"> // setup with one storefile and one memstore, to create scanner and get an earlier readPt</span>
<span class="source-line-no">6497</span><span id="line-6497"> Put put = new Put(Bytes.toBytes("19996"));</span>
<span class="source-line-no">6498</span><span id="line-6498"> put.addColumn(cf1, col, Bytes.toBytes("val"));</span>
<span class="source-line-no">6499</span><span id="line-6499"> region.put(put);</span>
<span class="source-line-no">6500</span><span id="line-6500"> Put put2 = new Put(Bytes.toBytes("19995"));</span>
<span class="source-line-no">6501</span><span id="line-6501"> put2.addColumn(cf1, col, Bytes.toBytes("val"));</span>
<span class="source-line-no">6502</span><span id="line-6502"> region.put(put2);</span>
<span class="source-line-no">6503</span><span id="line-6503"> // create a reverse scan</span>
<span class="source-line-no">6504</span><span id="line-6504"> Scan scan = new Scan().withStartRow(Bytes.toBytes("19996"));</span>
<span class="source-line-no">6505</span><span id="line-6505"> scan.setReversed(true);</span>
<span class="source-line-no">6506</span><span id="line-6506"> try (RegionScannerImpl scanner = region.getScanner(scan)) {</span>
<span class="source-line-no">6507</span><span id="line-6507"> // flush the cache. This will reset the store scanner</span>
<span class="source-line-no">6508</span><span id="line-6508"> region.flushcache(true, true, FlushLifeCycleTracker.DUMMY);</span>
<span class="source-line-no">6509</span><span id="line-6509"></span>
<span class="source-line-no">6510</span><span id="line-6510"> // create one memstore contains many rows will be skipped</span>
<span class="source-line-no">6511</span><span id="line-6511"> // to check MemStoreScanner.seekToPreviousRow</span>
<span class="source-line-no">6512</span><span id="line-6512"> for (int i = 10000; i &lt; 20000; i++) {</span>
<span class="source-line-no">6513</span><span id="line-6513"> Put p = new Put(Bytes.toBytes("" + i));</span>
<span class="source-line-no">6514</span><span id="line-6514"> p.addColumn(cf1, col, Bytes.toBytes("" + i));</span>
<span class="source-line-no">6515</span><span id="line-6515"> region.put(p);</span>
<span class="source-line-no">6516</span><span id="line-6516"> }</span>
<span class="source-line-no">6517</span><span id="line-6517"> List&lt;Cell&gt; currRow = new ArrayList&lt;&gt;();</span>
<span class="source-line-no">6518</span><span id="line-6518"> boolean hasNext;</span>
<span class="source-line-no">6519</span><span id="line-6519"> boolean assertDone = false;</span>
<span class="source-line-no">6520</span><span id="line-6520"> do {</span>
<span class="source-line-no">6521</span><span id="line-6521"> hasNext = scanner.next(currRow);</span>
<span class="source-line-no">6522</span><span id="line-6522"> // With HBASE-15871, after the scanner is reset the memstore scanner should not be</span>
<span class="source-line-no">6523</span><span id="line-6523"> // added here</span>
<span class="source-line-no">6524</span><span id="line-6524"> if (!assertDone) {</span>
<span class="source-line-no">6525</span><span id="line-6525"> StoreScanner current = (StoreScanner) (scanner.storeHeap).getCurrentForTesting();</span>
<span class="source-line-no">6526</span><span id="line-6526"> List&lt;KeyValueScanner&gt; scanners = current.getAllScannersForTesting();</span>
<span class="source-line-no">6527</span><span id="line-6527"> assertEquals("There should be only one scanner the store file scanner", 1,</span>
<span class="source-line-no">6528</span><span id="line-6528"> scanners.size());</span>
<span class="source-line-no">6529</span><span id="line-6529"> assertDone = true;</span>
<span class="source-line-no">6530</span><span id="line-6530"> }</span>
<span class="source-line-no">6531</span><span id="line-6531"> } while (hasNext);</span>
<span class="source-line-no">6532</span><span id="line-6532"> assertEquals(2, currRow.size());</span>
<span class="source-line-no">6533</span><span id="line-6533"> assertEquals("19996", Bytes.toString(currRow.get(0).getRowArray(),</span>
<span class="source-line-no">6534</span><span id="line-6534"> currRow.get(0).getRowOffset(), currRow.get(0).getRowLength()));</span>
<span class="source-line-no">6535</span><span id="line-6535"> assertEquals("19995", Bytes.toString(currRow.get(1).getRowArray(),</span>
<span class="source-line-no">6536</span><span id="line-6536"> currRow.get(1).getRowOffset(), currRow.get(1).getRowLength()));</span>
<span class="source-line-no">6537</span><span id="line-6537"> }</span>
<span class="source-line-no">6538</span><span id="line-6538"> }</span>
<span class="source-line-no">6539</span><span id="line-6539"></span>
<span class="source-line-no">6540</span><span id="line-6540"> @Test</span>
<span class="source-line-no">6541</span><span id="line-6541"> public void testReverseScanWhenPutCellsAfterOpenReverseScan() throws Exception {</span>
<span class="source-line-no">6542</span><span id="line-6542"> byte[] cf1 = Bytes.toBytes("CF1");</span>
<span class="source-line-no">6543</span><span id="line-6543"> byte[][] families = { cf1 };</span>
<span class="source-line-no">6544</span><span id="line-6544"> byte[] col = Bytes.toBytes("C");</span>
<span class="source-line-no">6545</span><span id="line-6545"></span>
<span class="source-line-no">6546</span><span id="line-6546"> this.region = initHRegion(tableName, method, CONF, families);</span>
<span class="source-line-no">6547</span><span id="line-6547"></span>
<span class="source-line-no">6548</span><span id="line-6548"> Put put = new Put(Bytes.toBytes("199996"));</span>
<span class="source-line-no">6549</span><span id="line-6549"> put.addColumn(cf1, col, Bytes.toBytes("val"));</span>
<span class="source-line-no">6550</span><span id="line-6550"> region.put(put);</span>
<span class="source-line-no">6551</span><span id="line-6551"> Put put2 = new Put(Bytes.toBytes("199995"));</span>
<span class="source-line-no">6552</span><span id="line-6552"> put2.addColumn(cf1, col, Bytes.toBytes("val"));</span>
<span class="source-line-no">6553</span><span id="line-6553"> region.put(put2);</span>
<span class="source-line-no">6554</span><span id="line-6554"></span>
<span class="source-line-no">6555</span><span id="line-6555"> // Create a reverse scan</span>
<span class="source-line-no">6556</span><span id="line-6556"> Scan scan = new Scan().withStartRow(Bytes.toBytes("199996"));</span>
<span class="source-line-no">6557</span><span id="line-6557"> scan.setReversed(true);</span>
<span class="source-line-no">6558</span><span id="line-6558"> try (RegionScannerImpl scanner = region.getScanner(scan)) {</span>
<span class="source-line-no">6559</span><span id="line-6559"> // Put a lot of cells that have sequenceIDs grater than the readPt of the reverse scan</span>
<span class="source-line-no">6560</span><span id="line-6560"> for (int i = 100000; i &lt; 200000; i++) {</span>
<span class="source-line-no">6561</span><span id="line-6561"> Put p = new Put(Bytes.toBytes("" + i));</span>
<span class="source-line-no">6562</span><span id="line-6562"> p.addColumn(cf1, col, Bytes.toBytes("" + i));</span>
<span class="source-line-no">6563</span><span id="line-6563"> region.put(p);</span>
<span class="source-line-no">6564</span><span id="line-6564"> }</span>
<span class="source-line-no">6565</span><span id="line-6565"> List&lt;Cell&gt; currRow = new ArrayList&lt;&gt;();</span>
<span class="source-line-no">6566</span><span id="line-6566"> boolean hasNext;</span>
<span class="source-line-no">6567</span><span id="line-6567"> do {</span>
<span class="source-line-no">6568</span><span id="line-6568"> hasNext = scanner.next(currRow);</span>
<span class="source-line-no">6569</span><span id="line-6569"> } while (hasNext);</span>
<span class="source-line-no">6570</span><span id="line-6570"></span>
<span class="source-line-no">6571</span><span id="line-6571"> assertEquals(2, currRow.size());</span>
<span class="source-line-no">6572</span><span id="line-6572"> assertEquals("199996", Bytes.toString(currRow.get(0).getRowArray(),</span>
<span class="source-line-no">6573</span><span id="line-6573"> currRow.get(0).getRowOffset(), currRow.get(0).getRowLength()));</span>
<span class="source-line-no">6574</span><span id="line-6574"> assertEquals("199995", Bytes.toString(currRow.get(1).getRowArray(),</span>
<span class="source-line-no">6575</span><span id="line-6575"> currRow.get(1).getRowOffset(), currRow.get(1).getRowLength()));</span>
<span class="source-line-no">6576</span><span id="line-6576"> }</span>
<span class="source-line-no">6577</span><span id="line-6577"> }</span>
<span class="source-line-no">6578</span><span id="line-6578"></span>
<span class="source-line-no">6579</span><span id="line-6579"> @Test</span>
<span class="source-line-no">6580</span><span id="line-6580"> public void testWriteRequestsCounter() throws IOException {</span>
<span class="source-line-no">6581</span><span id="line-6581"> byte[] fam = Bytes.toBytes("info");</span>
<span class="source-line-no">6582</span><span id="line-6582"> byte[][] families = { fam };</span>
<span class="source-line-no">6583</span><span id="line-6583"> this.region = initHRegion(tableName, method, CONF, families);</span>
<span class="source-line-no">6584</span><span id="line-6584"></span>
<span class="source-line-no">6585</span><span id="line-6585"> Assert.assertEquals(0L, region.getWriteRequestsCount());</span>
<span class="source-line-no">6586</span><span id="line-6586"></span>
<span class="source-line-no">6587</span><span id="line-6587"> Put put = new Put(row);</span>
<span class="source-line-no">6588</span><span id="line-6588"> put.addColumn(fam, fam, fam);</span>
<span class="source-line-no">6589</span><span id="line-6589"></span>
<span class="source-line-no">6590</span><span id="line-6590"> Assert.assertEquals(0L, 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(1L, 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(2L, region.getWriteRequestsCount());</span>
<span class="source-line-no">6595</span><span id="line-6595"> region.put(put);</span>
<span class="source-line-no">6596</span><span id="line-6596"> Assert.assertEquals(3L, region.getWriteRequestsCount());</span>
<span class="source-line-no">6597</span><span id="line-6597"></span>
<span class="source-line-no">6598</span><span id="line-6598"> region.delete(new Delete(row));</span>
<span class="source-line-no">6599</span><span id="line-6599"> Assert.assertEquals(4L, region.getWriteRequestsCount());</span>
<span class="source-line-no">6600</span><span id="line-6600"> }</span>
<span class="source-line-no">6601</span><span id="line-6601"></span>
<span class="source-line-no">6602</span><span id="line-6602"> @Test</span>
<span class="source-line-no">6603</span><span id="line-6603"> public void testOpenRegionWrittenToWAL() throws Exception {</span>
<span class="source-line-no">6604</span><span id="line-6604"> final ServerName serverName = ServerName.valueOf(name.getMethodName(), 100, 42);</span>
<span class="source-line-no">6605</span><span id="line-6605"> final RegionServerServices rss = spy(TEST_UTIL.createMockRegionServerService(serverName));</span>
<span class="source-line-no">6606</span><span id="line-6606"></span>
<span class="source-line-no">6607</span><span id="line-6607"> TableDescriptor htd = TableDescriptorBuilder.newBuilder(TableName.valueOf(name.getMethodName()))</span>
<span class="source-line-no">6608</span><span id="line-6608"> .setColumnFamily(ColumnFamilyDescriptorBuilder.of(fam1))</span>
<span class="source-line-no">6609</span><span id="line-6609"> .setColumnFamily(ColumnFamilyDescriptorBuilder.of(fam2)).build();</span>
<span class="source-line-no">6610</span><span id="line-6610"> RegionInfo hri = RegionInfoBuilder.newBuilder(htd.getTableName()).build();</span>
<span class="source-line-no">6611</span><span id="line-6611"></span>
<span class="source-line-no">6612</span><span id="line-6612"> // open the region w/o rss and wal and flush some files</span>
<span class="source-line-no">6613</span><span id="line-6613"> region = HBaseTestingUtil.createRegionAndWAL(hri, TEST_UTIL.getDataTestDir(),</span>
<span class="source-line-no">6614</span><span id="line-6614"> TEST_UTIL.getConfiguration(), htd);</span>
<span class="source-line-no">6615</span><span id="line-6615"> assertNotNull(region);</span>
<span class="source-line-no">6616</span><span id="line-6616"></span>
<span class="source-line-no">6617</span><span id="line-6617"> // create a file in fam1 for the region before opening in OpenRegionHandler</span>
<span class="source-line-no">6618</span><span id="line-6618"> region.put(new Put(Bytes.toBytes("a")).addColumn(fam1, fam1, fam1));</span>
<span class="source-line-no">6619</span><span id="line-6619"> region.flush(true);</span>
<span class="source-line-no">6620</span><span id="line-6620"> HBaseTestingUtil.closeRegionAndWAL(region);</span>
<span class="source-line-no">6621</span><span id="line-6621"></span>
<span class="source-line-no">6622</span><span id="line-6622"> ArgumentCaptor&lt;WALEdit&gt; editCaptor = ArgumentCaptor.forClass(WALEdit.class);</span>
<span class="source-line-no">6623</span><span id="line-6623"></span>
<span class="source-line-no">6624</span><span id="line-6624"> // capture append() calls</span>
<span class="source-line-no">6625</span><span id="line-6625"> WAL wal = mockWAL();</span>
<span class="source-line-no">6626</span><span id="line-6626"> when(rss.getWAL(any(RegionInfo.class))).thenReturn(wal);</span>
<span class="source-line-no">6627</span><span id="line-6627"></span>
<span class="source-line-no">6628</span><span id="line-6628"> region =</span>
<span class="source-line-no">6629</span><span id="line-6629"> HRegion.openHRegion(hri, htd, rss.getWAL(hri), TEST_UTIL.getConfiguration(), rss, null);</span>
<span class="source-line-no">6630</span><span id="line-6630"></span>
<span class="source-line-no">6631</span><span id="line-6631"> verify(wal, times(1)).appendMarker(any(RegionInfo.class), any(WALKeyImpl.class),</span>
<span class="source-line-no">6632</span><span id="line-6632"> editCaptor.capture());</span>
<span class="source-line-no">6633</span><span id="line-6633"></span>
<span class="source-line-no">6634</span><span id="line-6634"> WALEdit edit = editCaptor.getValue();</span>
<span class="source-line-no">6635</span><span id="line-6635"> assertNotNull(edit);</span>
<span class="source-line-no">6636</span><span id="line-6636"> assertNotNull(edit.getCells());</span>
<span class="source-line-no">6637</span><span id="line-6637"> assertEquals(1, edit.getCells().size());</span>
<span class="source-line-no">6638</span><span id="line-6638"> RegionEventDescriptor desc = WALEdit.getRegionEventDescriptor(edit.getCells().get(0));</span>
<span class="source-line-no">6639</span><span id="line-6639"> assertNotNull(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"> LOG.info("RegionEventDescriptor from WAL: " + desc);</span>
<span class="source-line-no">6642</span><span id="line-6642"></span>
<span class="source-line-no">6643</span><span id="line-6643"> assertEquals(RegionEventDescriptor.EventType.REGION_OPEN, desc.getEventType());</span>
<span class="source-line-no">6644</span><span id="line-6644"> assertTrue(Bytes.equals(desc.getTableName().toByteArray(), htd.getTableName().toBytes()));</span>
<span class="source-line-no">6645</span><span id="line-6645"> assertTrue(</span>
<span class="source-line-no">6646</span><span id="line-6646"> Bytes.equals(desc.getEncodedRegionName().toByteArray(), hri.getEncodedNameAsBytes()));</span>
<span class="source-line-no">6647</span><span id="line-6647"> assertTrue(desc.getLogSequenceNumber() &gt; 0);</span>
<span class="source-line-no">6648</span><span id="line-6648"> assertEquals(serverName, ProtobufUtil.toServerName(desc.getServer()));</span>
<span class="source-line-no">6649</span><span id="line-6649"> assertEquals(2, desc.getStoresCount());</span>
<span class="source-line-no">6650</span><span id="line-6650"></span>
<span class="source-line-no">6651</span><span id="line-6651"> StoreDescriptor store = desc.getStores(0);</span>
<span class="source-line-no">6652</span><span id="line-6652"> assertTrue(Bytes.equals(store.getFamilyName().toByteArray(), fam1));</span>
<span class="source-line-no">6653</span><span id="line-6653"> assertEquals(store.getStoreHomeDir(), Bytes.toString(fam1));</span>
<span class="source-line-no">6654</span><span id="line-6654"> assertEquals(1, store.getStoreFileCount()); // 1store file</span>
<span class="source-line-no">6655</span><span id="line-6655"> assertFalse(store.getStoreFile(0).contains("/")); // ensure path is relative</span>
<span class="source-line-no">6656</span><span id="line-6656"></span>
<span class="source-line-no">6657</span><span id="line-6657"> store = desc.getStores(1);</span>
<span class="source-line-no">6658</span><span id="line-6658"> assertTrue(Bytes.equals(store.getFamilyName().toByteArray(), fam2));</span>
<span class="source-line-no">6659</span><span id="line-6659"> assertEquals(store.getStoreHomeDir(), Bytes.toString(fam2));</span>
<span class="source-line-no">6660</span><span id="line-6660"> assertEquals(0, store.getStoreFileCount()); // no store files</span>
<span class="source-line-no">6661</span><span id="line-6661"> }</span>
<span class="source-line-no">6662</span><span id="line-6662"></span>
<span class="source-line-no">6663</span><span id="line-6663"> // Helper for test testOpenRegionWrittenToWALForLogReplay</span>
<span class="source-line-no">6664</span><span id="line-6664"> static class HRegionWithSeqId extends HRegion {</span>
<span class="source-line-no">6665</span><span id="line-6665"> public HRegionWithSeqId(final Path tableDir, final WAL wal, final FileSystem fs,</span>
<span class="source-line-no">6666</span><span id="line-6666"> final Configuration confParam, final RegionInfo regionInfo, final TableDescriptor htd,</span>
<span class="source-line-no">6667</span><span id="line-6667"> final RegionServerServices rsServices) {</span>
<span class="source-line-no">6668</span><span id="line-6668"> super(tableDir, wal, fs, confParam, regionInfo, htd, rsServices);</span>
<span class="source-line-no">6669</span><span id="line-6669"> }</span>
<span class="source-line-no">6670</span><span id="line-6670"></span>
<span class="source-line-no">6671</span><span id="line-6671"> @Override</span>
<span class="source-line-no">6672</span><span id="line-6672"> protected long getNextSequenceId(WAL wal) throws IOException {</span>
<span class="source-line-no">6673</span><span id="line-6673"> return 42;</span>
<span class="source-line-no">6674</span><span id="line-6674"> }</span>
<span class="source-line-no">6675</span><span id="line-6675"> }</span>
<span class="source-line-no">6676</span><span id="line-6676"></span>
<span class="source-line-no">6677</span><span id="line-6677"> @Test</span>
<span class="source-line-no">6678</span><span id="line-6678"> public void testFlushedFileWithNoTags() throws Exception {</span>
<span class="source-line-no">6679</span><span id="line-6679"> final TableName tableName = TableName.valueOf(name.getMethodName());</span>
<span class="source-line-no">6680</span><span id="line-6680"> TableDescriptor tableDescriptor = TableDescriptorBuilder.newBuilder(tableName)</span>
<span class="source-line-no">6681</span><span id="line-6681"> .setColumnFamily(ColumnFamilyDescriptorBuilder.of(fam1)).build();</span>
<span class="source-line-no">6682</span><span id="line-6682"> RegionInfo info = RegionInfoBuilder.newBuilder(tableName).build();</span>
<span class="source-line-no">6683</span><span id="line-6683"> Path path = TEST_UTIL.getDataTestDir(getClass().getSimpleName());</span>
<span class="source-line-no">6684</span><span id="line-6684"> region = HBaseTestingUtil.createRegionAndWAL(info, path, TEST_UTIL.getConfiguration(),</span>
<span class="source-line-no">6685</span><span id="line-6685"> tableDescriptor);</span>
<span class="source-line-no">6686</span><span id="line-6686"> Put put = new Put(Bytes.toBytes("a-b-0-0"));</span>
<span class="source-line-no">6687</span><span id="line-6687"> put.addColumn(fam1, qual1, Bytes.toBytes("c1-value"));</span>
<span class="source-line-no">6688</span><span id="line-6688"> region.put(put);</span>
<span class="source-line-no">6689</span><span id="line-6689"> region.flush(true);</span>
<span class="source-line-no">6690</span><span id="line-6690"> HStore store = region.getStore(fam1);</span>
<span class="source-line-no">6691</span><span id="line-6691"> Collection&lt;HStoreFile&gt; storefiles = store.getStorefiles();</span>
<span class="source-line-no">6692</span><span id="line-6692"> for (HStoreFile sf : storefiles) {</span>
<span class="source-line-no">6693</span><span id="line-6693"> assertFalse("Tags should not be present ",</span>
<span class="source-line-no">6694</span><span id="line-6694"> sf.getReader().getHFileReader().getFileContext().isIncludesTags());</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"></span>
<span class="source-line-no">6698</span><span id="line-6698"> /**</span>
<span class="source-line-no">6699</span><span id="line-6699"> * Utility method to setup a WAL mock.</span>
<span class="source-line-no">6700</span><span id="line-6700"> * &lt;p/&gt;</span>
<span class="source-line-no">6701</span><span id="line-6701"> * Needs to do the bit where we close latch on the WALKeyImpl on append else test hangs.</span>
<span class="source-line-no">6702</span><span id="line-6702"> * @return a mock WAL</span>
<span class="source-line-no">6703</span><span id="line-6703"> */</span>
<span class="source-line-no">6704</span><span id="line-6704"> private WAL mockWAL() throws IOException {</span>
<span class="source-line-no">6705</span><span id="line-6705"> WAL wal = mock(WAL.class);</span>
<span class="source-line-no">6706</span><span id="line-6706"> when(wal.appendData(any(RegionInfo.class), any(WALKeyImpl.class), any(WALEdit.class)))</span>
<span class="source-line-no">6707</span><span id="line-6707"> .thenAnswer(new Answer&lt;Long&gt;() {</span>
<span class="source-line-no">6708</span><span id="line-6708"> @Override</span>
<span class="source-line-no">6709</span><span id="line-6709"> public Long answer(InvocationOnMock invocation) throws Throwable {</span>
<span class="source-line-no">6710</span><span id="line-6710"> WALKeyImpl key = invocation.getArgument(1);</span>
<span class="source-line-no">6711</span><span id="line-6711"> MultiVersionConcurrencyControl.WriteEntry we = key.getMvcc().begin();</span>
<span class="source-line-no">6712</span><span id="line-6712"> key.setWriteEntry(we);</span>
<span class="source-line-no">6713</span><span id="line-6713"> return 1L;</span>
<span class="source-line-no">6714</span><span id="line-6714"> }</span>
<span class="source-line-no">6715</span><span id="line-6715"> });</span>
<span class="source-line-no">6716</span><span id="line-6716"> when(wal.appendMarker(any(RegionInfo.class), any(WALKeyImpl.class), any(WALEdit.class)))</span>
<span class="source-line-no">6717</span><span id="line-6717"> .thenAnswer(new Answer&lt;Long&gt;() {</span>
<span class="source-line-no">6718</span><span id="line-6718"> @Override</span>
<span class="source-line-no">6719</span><span id="line-6719"> public Long answer(InvocationOnMock invocation) throws Throwable {</span>
<span class="source-line-no">6720</span><span id="line-6720"> WALKeyImpl key = invocation.getArgument(1);</span>
<span class="source-line-no">6721</span><span id="line-6721"> MultiVersionConcurrencyControl.WriteEntry we = key.getMvcc().begin();</span>
<span class="source-line-no">6722</span><span id="line-6722"> key.setWriteEntry(we);</span>
<span class="source-line-no">6723</span><span id="line-6723"> return 1L;</span>
<span class="source-line-no">6724</span><span id="line-6724"> }</span>
<span class="source-line-no">6725</span><span id="line-6725"> });</span>
<span class="source-line-no">6726</span><span id="line-6726"> return wal;</span>
<span class="source-line-no">6727</span><span id="line-6727"> }</span>
<span class="source-line-no">6728</span><span id="line-6728"></span>
<span class="source-line-no">6729</span><span id="line-6729"> @Test</span>
<span class="source-line-no">6730</span><span id="line-6730"> public void testCloseRegionWrittenToWAL() throws Exception {</span>
<span class="source-line-no">6731</span><span id="line-6731"> Path rootDir = new Path(dir + name.getMethodName());</span>
<span class="source-line-no">6732</span><span id="line-6732"> CommonFSUtils.setRootDir(TEST_UTIL.getConfiguration(), rootDir);</span>
<span class="source-line-no">6733</span><span id="line-6733"></span>
<span class="source-line-no">6734</span><span id="line-6734"> final ServerName serverName = ServerName.valueOf("testCloseRegionWrittenToWAL", 100, 42);</span>
<span class="source-line-no">6735</span><span id="line-6735"> final RegionServerServices rss = spy(TEST_UTIL.createMockRegionServerService(serverName));</span>
<span class="source-line-no">6736</span><span id="line-6736"></span>
<span class="source-line-no">6737</span><span id="line-6737"> TableDescriptor htd = TableDescriptorBuilder.newBuilder(TableName.valueOf(name.getMethodName()))</span>
<span class="source-line-no">6738</span><span id="line-6738"> .setColumnFamily(ColumnFamilyDescriptorBuilder.of(fam1))</span>
<span class="source-line-no">6739</span><span id="line-6739"> .setColumnFamily(ColumnFamilyDescriptorBuilder.of(fam2)).build();</span>
<span class="source-line-no">6740</span><span id="line-6740"> RegionInfo hri = RegionInfoBuilder.newBuilder(htd.getTableName()).build();</span>
<span class="source-line-no">6741</span><span id="line-6741"></span>
<span class="source-line-no">6742</span><span id="line-6742"> ArgumentCaptor&lt;WALEdit&gt; editCaptor = ArgumentCaptor.forClass(WALEdit.class);</span>
<span class="source-line-no">6743</span><span id="line-6743"></span>
<span class="source-line-no">6744</span><span id="line-6744"> // capture append() calls</span>
<span class="source-line-no">6745</span><span id="line-6745"> WAL wal = mockWAL();</span>
<span class="source-line-no">6746</span><span id="line-6746"> when(rss.getWAL(any(RegionInfo.class))).thenReturn(wal);</span>
<span class="source-line-no">6747</span><span id="line-6747"></span>
<span class="source-line-no">6748</span><span id="line-6748"> // create the region</span>
<span class="source-line-no">6749</span><span id="line-6749"> region = HBaseTestingUtil.createRegionAndWAL(hri, rootDir, CONF, htd);</span>
<span class="source-line-no">6750</span><span id="line-6750"> HBaseTestingUtil.closeRegionAndWAL(region);</span>
<span class="source-line-no">6751</span><span id="line-6751"> region = null;</span>
<span class="source-line-no">6752</span><span id="line-6752"> // open the region first and then close it</span>
<span class="source-line-no">6753</span><span id="line-6753"> HRegion.openHRegion(hri, htd, rss.getWAL(hri), TEST_UTIL.getConfiguration(), rss, null).close();</span>
<span class="source-line-no">6754</span><span id="line-6754"></span>
<span class="source-line-no">6755</span><span id="line-6755"> // 2 times, one for region open, the other close region</span>
<span class="source-line-no">6756</span><span id="line-6756"> verify(wal, times(2)).appendMarker(any(RegionInfo.class), (WALKeyImpl) any(WALKeyImpl.class),</span>
<span class="source-line-no">6757</span><span id="line-6757"> editCaptor.capture());</span>
<span class="source-line-no">6758</span><span id="line-6758"></span>
<span class="source-line-no">6759</span><span id="line-6759"> WALEdit edit = editCaptor.getAllValues().get(1);</span>
<span class="source-line-no">6760</span><span id="line-6760"> assertNotNull(edit);</span>
<span class="source-line-no">6761</span><span id="line-6761"> assertNotNull(edit.getCells());</span>
<span class="source-line-no">6762</span><span id="line-6762"> assertEquals(1, edit.getCells().size());</span>
<span class="source-line-no">6763</span><span id="line-6763"> RegionEventDescriptor desc = WALEdit.getRegionEventDescriptor(edit.getCells().get(0));</span>
<span class="source-line-no">6764</span><span id="line-6764"> assertNotNull(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"> LOG.info("RegionEventDescriptor from WAL: " + desc);</span>
<span class="source-line-no">6767</span><span id="line-6767"></span>
<span class="source-line-no">6768</span><span id="line-6768"> assertEquals(RegionEventDescriptor.EventType.REGION_CLOSE, desc.getEventType());</span>
<span class="source-line-no">6769</span><span id="line-6769"> assertTrue(Bytes.equals(desc.getTableName().toByteArray(), htd.getTableName().toBytes()));</span>
<span class="source-line-no">6770</span><span id="line-6770"> assertTrue(</span>
<span class="source-line-no">6771</span><span id="line-6771"> Bytes.equals(desc.getEncodedRegionName().toByteArray(), hri.getEncodedNameAsBytes()));</span>
<span class="source-line-no">6772</span><span id="line-6772"> assertTrue(desc.getLogSequenceNumber() &gt; 0);</span>
<span class="source-line-no">6773</span><span id="line-6773"> assertEquals(serverName, ProtobufUtil.toServerName(desc.getServer()));</span>
<span class="source-line-no">6774</span><span id="line-6774"> assertEquals(2, desc.getStoresCount());</span>
<span class="source-line-no">6775</span><span id="line-6775"></span>
<span class="source-line-no">6776</span><span id="line-6776"> StoreDescriptor store = desc.getStores(0);</span>
<span class="source-line-no">6777</span><span id="line-6777"> assertTrue(Bytes.equals(store.getFamilyName().toByteArray(), fam1));</span>
<span class="source-line-no">6778</span><span id="line-6778"> assertEquals(store.getStoreHomeDir(), Bytes.toString(fam1));</span>
<span class="source-line-no">6779</span><span id="line-6779"> assertEquals(0, store.getStoreFileCount()); // no store files</span>
<span class="source-line-no">6780</span><span id="line-6780"></span>
<span class="source-line-no">6781</span><span id="line-6781"> store = desc.getStores(1);</span>
<span class="source-line-no">6782</span><span id="line-6782"> assertTrue(Bytes.equals(store.getFamilyName().toByteArray(), fam2));</span>
<span class="source-line-no">6783</span><span id="line-6783"> assertEquals(store.getStoreHomeDir(), Bytes.toString(fam2));</span>
<span class="source-line-no">6784</span><span id="line-6784"> assertEquals(0, store.getStoreFileCount()); // no store files</span>
<span class="source-line-no">6785</span><span id="line-6785"> }</span>
<span class="source-line-no">6786</span><span id="line-6786"></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 RegionTooBusyException thrown when region is busy</span>
<span class="source-line-no">6789</span><span id="line-6789"> */</span>
<span class="source-line-no">6790</span><span id="line-6790"> @Test</span>
<span class="source-line-no">6791</span><span id="line-6791"> public void testRegionTooBusy() throws IOException {</span>
<span class="source-line-no">6792</span><span id="line-6792"> byte[] family = Bytes.toBytes("family");</span>
<span class="source-line-no">6793</span><span id="line-6793"> long defaultBusyWaitDuration =</span>
<span class="source-line-no">6794</span><span id="line-6794"> CONF.getLong("hbase.busy.wait.duration", HRegion.DEFAULT_BUSY_WAIT_DURATION);</span>
<span class="source-line-no">6795</span><span id="line-6795"> CONF.setLong("hbase.busy.wait.duration", 1000);</span>
<span class="source-line-no">6796</span><span id="line-6796"> region = initHRegion(tableName, method, CONF, family);</span>
<span class="source-line-no">6797</span><span id="line-6797"> final AtomicBoolean stopped = new AtomicBoolean(true);</span>
<span class="source-line-no">6798</span><span id="line-6798"> Thread t = new Thread(new Runnable() {</span>
<span class="source-line-no">6799</span><span id="line-6799"> @Override</span>
<span class="source-line-no">6800</span><span id="line-6800"> public void run() {</span>
<span class="source-line-no">6801</span><span id="line-6801"> try {</span>
<span class="source-line-no">6802</span><span id="line-6802"> region.lock.writeLock().lock();</span>
<span class="source-line-no">6803</span><span id="line-6803"> stopped.set(false);</span>
<span class="source-line-no">6804</span><span id="line-6804"> while (!stopped.get()) {</span>
<span class="source-line-no">6805</span><span id="line-6805"> Thread.sleep(100);</span>
<span class="source-line-no">6806</span><span id="line-6806"> }</span>
<span class="source-line-no">6807</span><span id="line-6807"> } catch (InterruptedException ie) {</span>
<span class="source-line-no">6808</span><span id="line-6808"> } finally {</span>
<span class="source-line-no">6809</span><span id="line-6809"> region.lock.writeLock().unlock();</span>
<span class="source-line-no">6810</span><span id="line-6810"> }</span>
<span class="source-line-no">6811</span><span id="line-6811"> }</span>
<span class="source-line-no">6812</span><span id="line-6812"> });</span>
<span class="source-line-no">6813</span><span id="line-6813"> t.start();</span>
<span class="source-line-no">6814</span><span id="line-6814"> Get get = new Get(row);</span>
<span class="source-line-no">6815</span><span id="line-6815"> try {</span>
<span class="source-line-no">6816</span><span id="line-6816"> while (stopped.get()) {</span>
<span class="source-line-no">6817</span><span id="line-6817"> Thread.sleep(100);</span>
<span class="source-line-no">6818</span><span id="line-6818"> }</span>
<span class="source-line-no">6819</span><span id="line-6819"> region.get(get);</span>
<span class="source-line-no">6820</span><span id="line-6820"> fail("Should throw RegionTooBusyException");</span>
<span class="source-line-no">6821</span><span id="line-6821"> } catch (InterruptedException ie) {</span>
<span class="source-line-no">6822</span><span id="line-6822"> fail("test interrupted");</span>
<span class="source-line-no">6823</span><span id="line-6823"> } catch (RegionTooBusyException e) {</span>
<span class="source-line-no">6824</span><span id="line-6824"> // Good, expected</span>
<span class="source-line-no">6825</span><span id="line-6825"> } finally {</span>
<span class="source-line-no">6826</span><span id="line-6826"> stopped.set(true);</span>
<span class="source-line-no">6827</span><span id="line-6827"> try {</span>
<span class="source-line-no">6828</span><span id="line-6828"> t.join();</span>
<span class="source-line-no">6829</span><span id="line-6829"> } catch (Throwable e) {</span>
<span class="source-line-no">6830</span><span id="line-6830"> }</span>
<span class="source-line-no">6831</span><span id="line-6831"></span>
<span class="source-line-no">6832</span><span id="line-6832"> HBaseTestingUtil.closeRegionAndWAL(region);</span>
<span class="source-line-no">6833</span><span id="line-6833"> region = null;</span>
<span class="source-line-no">6834</span><span id="line-6834"> CONF.setLong("hbase.busy.wait.duration", defaultBusyWaitDuration);</span>
<span class="source-line-no">6835</span><span id="line-6835"> }</span>
<span class="source-line-no">6836</span><span id="line-6836"> }</span>
<span class="source-line-no">6837</span><span id="line-6837"></span>
<span class="source-line-no">6838</span><span id="line-6838"> @Test</span>
<span class="source-line-no">6839</span><span id="line-6839"> public void testCellTTLs() throws IOException {</span>
<span class="source-line-no">6840</span><span id="line-6840"> IncrementingEnvironmentEdge edge = new IncrementingEnvironmentEdge();</span>
<span class="source-line-no">6841</span><span id="line-6841"> EnvironmentEdgeManager.injectEdge(edge);</span>
<span class="source-line-no">6842</span><span id="line-6842"></span>
<span class="source-line-no">6843</span><span id="line-6843"> final byte[] row = Bytes.toBytes("testRow");</span>
<span class="source-line-no">6844</span><span id="line-6844"> final byte[] q1 = Bytes.toBytes("q1");</span>
<span class="source-line-no">6845</span><span id="line-6845"> final byte[] q2 = Bytes.toBytes("q2");</span>
<span class="source-line-no">6846</span><span id="line-6846"> final byte[] q3 = Bytes.toBytes("q3");</span>
<span class="source-line-no">6847</span><span id="line-6847"> final byte[] q4 = Bytes.toBytes("q4");</span>
<span class="source-line-no">6848</span><span id="line-6848"></span>
<span class="source-line-no">6849</span><span id="line-6849"> // 10 seconds</span>
<span class="source-line-no">6850</span><span id="line-6850"> TableDescriptor tableDescriptor =</span>
<span class="source-line-no">6851</span><span id="line-6851"> TableDescriptorBuilder.newBuilder(TableName.valueOf(name.getMethodName()))</span>
<span class="source-line-no">6852</span><span id="line-6852"> .setColumnFamily(ColumnFamilyDescriptorBuilder.newBuilder(fam1).setTimeToLive(10).build())</span>
<span class="source-line-no">6853</span><span id="line-6853"> .build();</span>
<span class="source-line-no">6854</span><span id="line-6854"></span>
<span class="source-line-no">6855</span><span id="line-6855"> Configuration conf = new Configuration(TEST_UTIL.getConfiguration());</span>
<span class="source-line-no">6856</span><span id="line-6856"> conf.setInt(HFile.FORMAT_VERSION_KEY, HFile.MIN_FORMAT_VERSION_WITH_TAGS);</span>
<span class="source-line-no">6857</span><span id="line-6857"></span>
<span class="source-line-no">6858</span><span id="line-6858"> region = HBaseTestingUtil.createRegionAndWAL(</span>
<span class="source-line-no">6859</span><span id="line-6859"> RegionInfoBuilder.newBuilder(tableDescriptor.getTableName()).build(),</span>
<span class="source-line-no">6860</span><span id="line-6860"> TEST_UTIL.getDataTestDir(), conf, tableDescriptor);</span>
<span class="source-line-no">6861</span><span id="line-6861"> assertNotNull(region);</span>
<span class="source-line-no">6862</span><span id="line-6862"> long now = EnvironmentEdgeManager.currentTime();</span>
<span class="source-line-no">6863</span><span id="line-6863"> // Add a cell that will expire in 5 seconds via cell TTL</span>
<span class="source-line-no">6864</span><span id="line-6864"> region.put(new Put(row).add(new KeyValue(row, fam1, q1, now, HConstants.EMPTY_BYTE_ARRAY,</span>
<span class="source-line-no">6865</span><span id="line-6865"> new ArrayBackedTag[] {</span>
<span class="source-line-no">6866</span><span id="line-6866"> // TTL tags specify ts in milliseconds</span>
<span class="source-line-no">6867</span><span id="line-6867"> new ArrayBackedTag(TagType.TTL_TAG_TYPE, Bytes.toBytes(5000L)) })));</span>
<span class="source-line-no">6868</span><span id="line-6868"> // Add a cell that will expire after 10 seconds via family setting</span>
<span class="source-line-no">6869</span><span id="line-6869"> region.put(new Put(row).addColumn(fam1, q2, now, HConstants.EMPTY_BYTE_ARRAY));</span>
<span class="source-line-no">6870</span><span id="line-6870"> // Add a cell that will expire in 15 seconds via cell TTL</span>
<span class="source-line-no">6871</span><span id="line-6871"> region.put(new Put(row).add(new KeyValue(row, fam1, q3, now + 10000 - 1,</span>
<span class="source-line-no">6872</span><span id="line-6872"> HConstants.EMPTY_BYTE_ARRAY, new ArrayBackedTag[] {</span>
<span class="source-line-no">6873</span><span id="line-6873"> // TTL tags specify ts in milliseconds</span>
<span class="source-line-no">6874</span><span id="line-6874"> new ArrayBackedTag(TagType.TTL_TAG_TYPE, Bytes.toBytes(5000L)) })));</span>
<span class="source-line-no">6875</span><span id="line-6875"> // Add a cell that will expire in 20 seconds via family setting</span>
<span class="source-line-no">6876</span><span id="line-6876"> region.put(new Put(row).addColumn(fam1, q4, now + 10000 - 1, HConstants.EMPTY_BYTE_ARRAY));</span>
<span class="source-line-no">6877</span><span id="line-6877"></span>
<span class="source-line-no">6878</span><span id="line-6878"> // Flush so we are sure store scanning gets this right</span>
<span class="source-line-no">6879</span><span id="line-6879"> region.flush(true);</span>
<span class="source-line-no">6880</span><span id="line-6880"></span>
<span class="source-line-no">6881</span><span id="line-6881"> // A query at time T+0 should return all cells</span>
<span class="source-line-no">6882</span><span id="line-6882"> Result r = region.get(new Get(row));</span>
<span class="source-line-no">6883</span><span id="line-6883"> assertNotNull(r.getValue(fam1, q1));</span>
<span class="source-line-no">6884</span><span id="line-6884"> assertNotNull(r.getValue(fam1, q2));</span>
<span class="source-line-no">6885</span><span id="line-6885"> assertNotNull(r.getValue(fam1, q3));</span>
<span class="source-line-no">6886</span><span id="line-6886"> assertNotNull(r.getValue(fam1, q4));</span>
<span class="source-line-no">6887</span><span id="line-6887"></span>
<span class="source-line-no">6888</span><span id="line-6888"> // Increment time to T+5 seconds</span>
<span class="source-line-no">6889</span><span id="line-6889"> edge.incrementTime(5000);</span>
<span class="source-line-no">6890</span><span id="line-6890"></span>
<span class="source-line-no">6891</span><span id="line-6891"> r = region.get(new Get(row));</span>
<span class="source-line-no">6892</span><span id="line-6892"> assertNull(r.getValue(fam1, q1));</span>
<span class="source-line-no">6893</span><span id="line-6893"> assertNotNull(r.getValue(fam1, q2));</span>
<span class="source-line-no">6894</span><span id="line-6894"> assertNotNull(r.getValue(fam1, q3));</span>
<span class="source-line-no">6895</span><span id="line-6895"> assertNotNull(r.getValue(fam1, q4));</span>
<span class="source-line-no">6896</span><span id="line-6896"></span>
<span class="source-line-no">6897</span><span id="line-6897"> // Increment time to T+10 seconds</span>
<span class="source-line-no">6898</span><span id="line-6898"> edge.incrementTime(5000);</span>
<span class="source-line-no">6899</span><span id="line-6899"></span>
<span class="source-line-no">6900</span><span id="line-6900"> r = region.get(new Get(row));</span>
<span class="source-line-no">6901</span><span id="line-6901"> assertNull(r.getValue(fam1, q1));</span>
<span class="source-line-no">6902</span><span id="line-6902"> assertNull(r.getValue(fam1, q2));</span>
<span class="source-line-no">6903</span><span id="line-6903"> assertNotNull(r.getValue(fam1, q3));</span>
<span class="source-line-no">6904</span><span id="line-6904"> assertNotNull(r.getValue(fam1, q4));</span>
<span class="source-line-no">6905</span><span id="line-6905"></span>
<span class="source-line-no">6906</span><span id="line-6906"> // Increment time to T+15 seconds</span>
<span class="source-line-no">6907</span><span id="line-6907"> edge.incrementTime(5000);</span>
<span class="source-line-no">6908</span><span id="line-6908"></span>
<span class="source-line-no">6909</span><span id="line-6909"> r = region.get(new Get(row));</span>
<span class="source-line-no">6910</span><span id="line-6910"> assertNull(r.getValue(fam1, q1));</span>
<span class="source-line-no">6911</span><span id="line-6911"> assertNull(r.getValue(fam1, q2));</span>
<span class="source-line-no">6912</span><span id="line-6912"> assertNull(r.getValue(fam1, q3));</span>
<span class="source-line-no">6913</span><span id="line-6913"> assertNotNull(r.getValue(fam1, q4));</span>
<span class="source-line-no">6914</span><span id="line-6914"></span>
<span class="source-line-no">6915</span><span id="line-6915"> // Increment time to T+20 seconds</span>
<span class="source-line-no">6916</span><span id="line-6916"> edge.incrementTime(10000);</span>
<span class="source-line-no">6917</span><span id="line-6917"></span>
<span class="source-line-no">6918</span><span id="line-6918"> r = region.get(new Get(row));</span>
<span class="source-line-no">6919</span><span id="line-6919"> assertNull(r.getValue(fam1, q1));</span>
<span class="source-line-no">6920</span><span id="line-6920"> assertNull(r.getValue(fam1, q2));</span>
<span class="source-line-no">6921</span><span id="line-6921"> assertNull(r.getValue(fam1, q3));</span>
<span class="source-line-no">6922</span><span id="line-6922"> assertNull(r.getValue(fam1, q4));</span>
<span class="source-line-no">6923</span><span id="line-6923"></span>
<span class="source-line-no">6924</span><span id="line-6924"> // Fun with disappearing increments</span>
<span class="source-line-no">6925</span><span id="line-6925"></span>
<span class="source-line-no">6926</span><span id="line-6926"> // Start at 1</span>
<span class="source-line-no">6927</span><span id="line-6927"> region.put(new Put(row).addColumn(fam1, q1, Bytes.toBytes(1L)));</span>
<span class="source-line-no">6928</span><span id="line-6928"> r = region.get(new Get(row));</span>
<span class="source-line-no">6929</span><span id="line-6929"> byte[] val = r.getValue(fam1, q1);</span>
<span class="source-line-no">6930</span><span id="line-6930"> assertNotNull(val);</span>
<span class="source-line-no">6931</span><span id="line-6931"> assertEquals(1L, Bytes.toLong(val));</span>
<span class="source-line-no">6932</span><span id="line-6932"></span>
<span class="source-line-no">6933</span><span id="line-6933"> // Increment with a TTL of 5 seconds</span>
<span class="source-line-no">6934</span><span id="line-6934"> Increment incr = new Increment(row).addColumn(fam1, q1, 1L);</span>
<span class="source-line-no">6935</span><span id="line-6935"> incr.setTTL(5000);</span>
<span class="source-line-no">6936</span><span id="line-6936"> region.increment(incr); // 2</span>
<span class="source-line-no">6937</span><span id="line-6937"></span>
<span class="source-line-no">6938</span><span id="line-6938"> // New value should be 2</span>
<span class="source-line-no">6939</span><span id="line-6939"> r = region.get(new Get(row));</span>
<span class="source-line-no">6940</span><span id="line-6940"> val = r.getValue(fam1, q1);</span>
<span class="source-line-no">6941</span><span id="line-6941"> assertNotNull(val);</span>
<span class="source-line-no">6942</span><span id="line-6942"> assertEquals(2L, Bytes.toLong(val));</span>
<span class="source-line-no">6943</span><span id="line-6943"></span>
<span class="source-line-no">6944</span><span id="line-6944"> // Increment time to T+25 seconds</span>
<span class="source-line-no">6945</span><span id="line-6945"> edge.incrementTime(5000);</span>
<span class="source-line-no">6946</span><span id="line-6946"></span>
<span class="source-line-no">6947</span><span id="line-6947"> // Value should be back to 1</span>
<span class="source-line-no">6948</span><span id="line-6948"> r = region.get(new Get(row));</span>
<span class="source-line-no">6949</span><span id="line-6949"> val = r.getValue(fam1, q1);</span>
<span class="source-line-no">6950</span><span id="line-6950"> assertNotNull(val);</span>
<span class="source-line-no">6951</span><span id="line-6951"> assertEquals(1L, Bytes.toLong(val));</span>
<span class="source-line-no">6952</span><span id="line-6952"></span>
<span class="source-line-no">6953</span><span id="line-6953"> // Increment time to T+30 seconds</span>
<span class="source-line-no">6954</span><span id="line-6954"> edge.incrementTime(5000);</span>
<span class="source-line-no">6955</span><span id="line-6955"></span>
<span class="source-line-no">6956</span><span id="line-6956"> // Original value written at T+20 should be gone now via family TTL</span>
<span class="source-line-no">6957</span><span id="line-6957"> r = region.get(new Get(row));</span>
<span class="source-line-no">6958</span><span id="line-6958"> assertNull(r.getValue(fam1, q1));</span>
<span class="source-line-no">6959</span><span id="line-6959"> }</span>
<span class="source-line-no">6960</span><span id="line-6960"></span>
<span class="source-line-no">6961</span><span id="line-6961"> @Test</span>
<span class="source-line-no">6962</span><span id="line-6962"> public void testTTLsUsingSmallHeartBeatCells() throws IOException {</span>
<span class="source-line-no">6963</span><span id="line-6963"> IncrementingEnvironmentEdge edge = new IncrementingEnvironmentEdge();</span>
<span class="source-line-no">6964</span><span id="line-6964"> EnvironmentEdgeManager.injectEdge(edge);</span>
<span class="source-line-no">6965</span><span id="line-6965"></span>
<span class="source-line-no">6966</span><span id="line-6966"> final byte[] row = Bytes.toBytes("testRow");</span>
<span class="source-line-no">6967</span><span id="line-6967"> final byte[] q1 = Bytes.toBytes("q1");</span>
<span class="source-line-no">6968</span><span id="line-6968"> final byte[] q2 = Bytes.toBytes("q2");</span>
<span class="source-line-no">6969</span><span id="line-6969"> final byte[] q3 = Bytes.toBytes("q3");</span>
<span class="source-line-no">6970</span><span id="line-6970"> final byte[] q4 = Bytes.toBytes("q4");</span>
<span class="source-line-no">6971</span><span id="line-6971"> final byte[] q5 = Bytes.toBytes("q5");</span>
<span class="source-line-no">6972</span><span id="line-6972"> final byte[] q6 = Bytes.toBytes("q6");</span>
<span class="source-line-no">6973</span><span id="line-6973"> final byte[] q7 = Bytes.toBytes("q7");</span>
<span class="source-line-no">6974</span><span id="line-6974"> final byte[] q8 = Bytes.toBytes("q8");</span>
<span class="source-line-no">6975</span><span id="line-6975"></span>
<span class="source-line-no">6976</span><span id="line-6976"> // 10 seconds</span>
<span class="source-line-no">6977</span><span id="line-6977"> int ttlSecs = 10;</span>
<span class="source-line-no">6978</span><span id="line-6978"> TableDescriptor tableDescriptor =</span>
<span class="source-line-no">6979</span><span id="line-6979"> TableDescriptorBuilder.newBuilder(TableName.valueOf(name.getMethodName())).setColumnFamily(</span>
<span class="source-line-no">6980</span><span id="line-6980"> ColumnFamilyDescriptorBuilder.newBuilder(fam1).setTimeToLive(ttlSecs).build()).build();</span>
<span class="source-line-no">6981</span><span id="line-6981"></span>
<span class="source-line-no">6982</span><span id="line-6982"> Configuration conf = new Configuration(TEST_UTIL.getConfiguration());</span>
<span class="source-line-no">6983</span><span id="line-6983"> conf.setInt(HFile.FORMAT_VERSION_KEY, HFile.MIN_FORMAT_VERSION_WITH_TAGS);</span>
<span class="source-line-no">6984</span><span id="line-6984"> // using small heart beat cells</span>
<span class="source-line-no">6985</span><span id="line-6985"> conf.setLong(StoreScanner.HBASE_CELLS_SCANNED_PER_HEARTBEAT_CHECK, 2);</span>
<span class="source-line-no">6986</span><span id="line-6986"></span>
<span class="source-line-no">6987</span><span id="line-6987"> region = HBaseTestingUtil.createRegionAndWAL(</span>
<span class="source-line-no">6988</span><span id="line-6988"> RegionInfoBuilder.newBuilder(tableDescriptor.getTableName()).build(),</span>
<span class="source-line-no">6989</span><span id="line-6989"> TEST_UTIL.getDataTestDir(), conf, tableDescriptor);</span>
<span class="source-line-no">6990</span><span id="line-6990"> assertNotNull(region);</span>
<span class="source-line-no">6991</span><span id="line-6991"> long now = EnvironmentEdgeManager.currentTime();</span>
<span class="source-line-no">6992</span><span id="line-6992"> // Add a cell that will expire in 5 seconds via cell TTL</span>
<span class="source-line-no">6993</span><span id="line-6993"> region.put(new Put(row).addColumn(fam1, q1, now, HConstants.EMPTY_BYTE_ARRAY));</span>
<span class="source-line-no">6994</span><span id="line-6994"> region.put(new Put(row).addColumn(fam1, q2, now, HConstants.EMPTY_BYTE_ARRAY));</span>
<span class="source-line-no">6995</span><span id="line-6995"> region.put(new Put(row).addColumn(fam1, q3, now, HConstants.EMPTY_BYTE_ARRAY));</span>
<span class="source-line-no">6996</span><span id="line-6996"> // Add a cell that will expire after 10 seconds via family setting</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, q4, now + ttlSecs * 1000 + 1, HConstants.EMPTY_BYTE_ARRAY));</span>
<span class="source-line-no">6999</span><span id="line-6999"> region</span>
<span class="source-line-no">7000</span><span id="line-7000"> .put(new Put(row).addColumn(fam1, q5, now + ttlSecs * 1000 + 1, HConstants.EMPTY_BYTE_ARRAY));</span>
<span class="source-line-no">7001</span><span id="line-7001"></span>
<span class="source-line-no">7002</span><span id="line-7002"> region.put(new Put(row).addColumn(fam1, q6, now, HConstants.EMPTY_BYTE_ARRAY));</span>
<span class="source-line-no">7003</span><span id="line-7003"> region.put(new Put(row).addColumn(fam1, q7, now, HConstants.EMPTY_BYTE_ARRAY));</span>
<span class="source-line-no">7004</span><span id="line-7004"> region</span>
<span class="source-line-no">7005</span><span id="line-7005"> .put(new Put(row).addColumn(fam1, q8, now + ttlSecs * 1000 + 1, HConstants.EMPTY_BYTE_ARRAY));</span>
<span class="source-line-no">7006</span><span id="line-7006"></span>
<span class="source-line-no">7007</span><span id="line-7007"> // Flush so we are sure store scanning gets this right</span>
<span class="source-line-no">7008</span><span id="line-7008"> region.flush(true);</span>
<span class="source-line-no">7009</span><span id="line-7009"></span>
<span class="source-line-no">7010</span><span id="line-7010"> // A query at time T+0 should return all cells</span>
<span class="source-line-no">7011</span><span id="line-7011"> checkScan(8);</span>
<span class="source-line-no">7012</span><span id="line-7012"> region.delete(new Delete(row).addColumn(fam1, q8));</span>
<span class="source-line-no">7013</span><span id="line-7013"></span>
<span class="source-line-no">7014</span><span id="line-7014"> // Increment time to T+ttlSecs seconds</span>
<span class="source-line-no">7015</span><span id="line-7015"> edge.incrementTime(ttlSecs * 1000);</span>
<span class="source-line-no">7016</span><span id="line-7016"> checkScan(2);</span>
<span class="source-line-no">7017</span><span id="line-7017"> }</span>
<span class="source-line-no">7018</span><span id="line-7018"></span>
<span class="source-line-no">7019</span><span id="line-7019"> private void checkScan(int expectCellSize) throws IOException {</span>
<span class="source-line-no">7020</span><span id="line-7020"> Scan s = new Scan().withStartRow(row);</span>
<span class="source-line-no">7021</span><span id="line-7021"> ScannerContext.Builder contextBuilder = ScannerContext.newBuilder(true);</span>
<span class="source-line-no">7022</span><span id="line-7022"> ScannerContext scannerContext = contextBuilder.build();</span>
<span class="source-line-no">7023</span><span id="line-7023"> try (RegionScanner scanner = region.getScanner(s)) {</span>
<span class="source-line-no">7024</span><span id="line-7024"> List&lt;Cell&gt; kvs = new ArrayList&lt;&gt;();</span>
<span class="source-line-no">7025</span><span id="line-7025"> scanner.next(kvs, scannerContext);</span>
<span class="source-line-no">7026</span><span id="line-7026"> assertEquals(expectCellSize, kvs.size());</span>
<span class="source-line-no">7027</span><span id="line-7027"> }</span>
<span class="source-line-no">7028</span><span id="line-7028"> }</span>
<span class="source-line-no">7029</span><span id="line-7029"></span>
<span class="source-line-no">7030</span><span id="line-7030"> @Test</span>
<span class="source-line-no">7031</span><span id="line-7031"> public void testIncrementTimestampsAreMonotonic() throws IOException {</span>
<span class="source-line-no">7032</span><span id="line-7032"> region = initHRegion(tableName, method, CONF, fam1);</span>
<span class="source-line-no">7033</span><span id="line-7033"> ManualEnvironmentEdge edge = new ManualEnvironmentEdge();</span>
<span class="source-line-no">7034</span><span id="line-7034"> EnvironmentEdgeManager.injectEdge(edge);</span>
<span class="source-line-no">7035</span><span id="line-7035"></span>
<span class="source-line-no">7036</span><span id="line-7036"> edge.setValue(10);</span>
<span class="source-line-no">7037</span><span id="line-7037"> Increment inc = new Increment(row);</span>
<span class="source-line-no">7038</span><span id="line-7038"> inc.setDurability(Durability.SKIP_WAL);</span>
<span class="source-line-no">7039</span><span id="line-7039"> inc.addColumn(fam1, qual1, 1L);</span>
<span class="source-line-no">7040</span><span id="line-7040"> region.increment(inc);</span>
<span class="source-line-no">7041</span><span id="line-7041"></span>
<span class="source-line-no">7042</span><span id="line-7042"> Result result = region.get(new Get(row));</span>
<span class="source-line-no">7043</span><span id="line-7043"> Cell c = result.getColumnLatestCell(fam1, qual1);</span>
<span class="source-line-no">7044</span><span id="line-7044"> assertNotNull(c);</span>
<span class="source-line-no">7045</span><span id="line-7045"> assertEquals(10L, c.getTimestamp());</span>
<span class="source-line-no">7046</span><span id="line-7046"></span>
<span class="source-line-no">7047</span><span id="line-7047"> edge.setValue(1); // clock goes back</span>
<span class="source-line-no">7048</span><span id="line-7048"> region.increment(inc);</span>
<span class="source-line-no">7049</span><span id="line-7049"> result = region.get(new Get(row));</span>
<span class="source-line-no">7050</span><span id="line-7050"> c = result.getColumnLatestCell(fam1, qual1);</span>
<span class="source-line-no">7051</span><span id="line-7051"> assertEquals(11L, c.getTimestamp());</span>
<span class="source-line-no">7052</span><span id="line-7052"> assertEquals(2L, Bytes.toLong(c.getValueArray(), c.getValueOffset(), c.getValueLength()));</span>
<span class="source-line-no">7053</span><span id="line-7053"> }</span>
<span class="source-line-no">7054</span><span id="line-7054"></span>
<span class="source-line-no">7055</span><span id="line-7055"> @Test</span>
<span class="source-line-no">7056</span><span id="line-7056"> public void testAppendTimestampsAreMonotonic() throws IOException {</span>
<span class="source-line-no">7057</span><span id="line-7057"> region = initHRegion(tableName, method, CONF, fam1);</span>
<span class="source-line-no">7058</span><span id="line-7058"> ManualEnvironmentEdge edge = new ManualEnvironmentEdge();</span>
<span class="source-line-no">7059</span><span id="line-7059"> EnvironmentEdgeManager.injectEdge(edge);</span>
<span class="source-line-no">7060</span><span id="line-7060"></span>
<span class="source-line-no">7061</span><span id="line-7061"> edge.setValue(10);</span>
<span class="source-line-no">7062</span><span id="line-7062"> Append a = new Append(row);</span>
<span class="source-line-no">7063</span><span id="line-7063"> a.setDurability(Durability.SKIP_WAL);</span>
<span class="source-line-no">7064</span><span id="line-7064"> a.addColumn(fam1, qual1, qual1);</span>
<span class="source-line-no">7065</span><span id="line-7065"> region.append(a);</span>
<span class="source-line-no">7066</span><span id="line-7066"></span>
<span class="source-line-no">7067</span><span id="line-7067"> Result result = region.get(new Get(row));</span>
<span class="source-line-no">7068</span><span id="line-7068"> Cell c = result.getColumnLatestCell(fam1, qual1);</span>
<span class="source-line-no">7069</span><span id="line-7069"> assertNotNull(c);</span>
<span class="source-line-no">7070</span><span id="line-7070"> assertEquals(10L, c.getTimestamp());</span>
<span class="source-line-no">7071</span><span id="line-7071"></span>
<span class="source-line-no">7072</span><span id="line-7072"> edge.setValue(1); // clock goes back</span>
<span class="source-line-no">7073</span><span id="line-7073"> region.append(a);</span>
<span class="source-line-no">7074</span><span id="line-7074"> result = region.get(new Get(row));</span>
<span class="source-line-no">7075</span><span id="line-7075"> c = result.getColumnLatestCell(fam1, qual1);</span>
<span class="source-line-no">7076</span><span id="line-7076"> assertEquals(11L, c.getTimestamp());</span>
<span class="source-line-no">7077</span><span id="line-7077"></span>
<span class="source-line-no">7078</span><span id="line-7078"> byte[] expected = new byte[qual1.length * 2];</span>
<span class="source-line-no">7079</span><span id="line-7079"> System.arraycopy(qual1, 0, expected, 0, qual1.length);</span>
<span class="source-line-no">7080</span><span id="line-7080"> System.arraycopy(qual1, 0, expected, qual1.length, qual1.length);</span>
<span class="source-line-no">7081</span><span id="line-7081"></span>
<span class="source-line-no">7082</span><span id="line-7082"> assertTrue(Bytes.equals(c.getValueArray(), c.getValueOffset(), c.getValueLength(), expected, 0,</span>
<span class="source-line-no">7083</span><span id="line-7083"> expected.length));</span>
<span class="source-line-no">7084</span><span id="line-7084"> }</span>
<span class="source-line-no">7085</span><span id="line-7085"></span>
<span class="source-line-no">7086</span><span id="line-7086"> @Test</span>
<span class="source-line-no">7087</span><span id="line-7087"> public void testCheckAndMutateTimestampsAreMonotonic() throws IOException {</span>
<span class="source-line-no">7088</span><span id="line-7088"> region = initHRegion(tableName, method, CONF, fam1);</span>
<span class="source-line-no">7089</span><span id="line-7089"> ManualEnvironmentEdge edge = new ManualEnvironmentEdge();</span>
<span class="source-line-no">7090</span><span id="line-7090"> EnvironmentEdgeManager.injectEdge(edge);</span>
<span class="source-line-no">7091</span><span id="line-7091"></span>
<span class="source-line-no">7092</span><span id="line-7092"> edge.setValue(10);</span>
<span class="source-line-no">7093</span><span id="line-7093"> Put p = new Put(row);</span>
<span class="source-line-no">7094</span><span id="line-7094"> p.setDurability(Durability.SKIP_WAL);</span>
<span class="source-line-no">7095</span><span id="line-7095"> p.addColumn(fam1, qual1, qual1);</span>
<span class="source-line-no">7096</span><span id="line-7096"> region.put(p);</span>
<span class="source-line-no">7097</span><span id="line-7097"></span>
<span class="source-line-no">7098</span><span id="line-7098"> Result result = region.get(new Get(row));</span>
<span class="source-line-no">7099</span><span id="line-7099"> Cell c = result.getColumnLatestCell(fam1, qual1);</span>
<span class="source-line-no">7100</span><span id="line-7100"> assertNotNull(c);</span>
<span class="source-line-no">7101</span><span id="line-7101"> assertEquals(10L, c.getTimestamp());</span>
<span class="source-line-no">7102</span><span id="line-7102"></span>
<span class="source-line-no">7103</span><span id="line-7103"> edge.setValue(1); // clock goes back</span>
<span class="source-line-no">7104</span><span id="line-7104"> p = new Put(row);</span>
<span class="source-line-no">7105</span><span id="line-7105"> p.setDurability(Durability.SKIP_WAL);</span>
<span class="source-line-no">7106</span><span id="line-7106"> p.addColumn(fam1, qual1, qual2);</span>
<span class="source-line-no">7107</span><span id="line-7107"> region.checkAndMutate(row, fam1, qual1, CompareOperator.EQUAL, new BinaryComparator(qual1), p);</span>
<span class="source-line-no">7108</span><span id="line-7108"> result = region.get(new Get(row));</span>
<span class="source-line-no">7109</span><span id="line-7109"> c = result.getColumnLatestCell(fam1, qual1);</span>
<span class="source-line-no">7110</span><span id="line-7110"> assertEquals(10L, c.getTimestamp());</span>
<span class="source-line-no">7111</span><span id="line-7111"></span>
<span class="source-line-no">7112</span><span id="line-7112"> assertTrue(Bytes.equals(c.getValueArray(), c.getValueOffset(), c.getValueLength(), qual2, 0,</span>
<span class="source-line-no">7113</span><span id="line-7113"> qual2.length));</span>
<span class="source-line-no">7114</span><span id="line-7114"> }</span>
<span class="source-line-no">7115</span><span id="line-7115"></span>
<span class="source-line-no">7116</span><span id="line-7116"> @Test</span>
<span class="source-line-no">7117</span><span id="line-7117"> public void testBatchMutateWithWrongRegionException() throws Exception {</span>
<span class="source-line-no">7118</span><span id="line-7118"> final byte[] a = Bytes.toBytes("a");</span>
<span class="source-line-no">7119</span><span id="line-7119"> final byte[] b = Bytes.toBytes("b");</span>
<span class="source-line-no">7120</span><span id="line-7120"> final byte[] c = Bytes.toBytes("c"); // exclusive</span>
<span class="source-line-no">7121</span><span id="line-7121"></span>
<span class="source-line-no">7122</span><span id="line-7122"> int prevLockTimeout = CONF.getInt("hbase.rowlock.wait.duration", 30000);</span>
<span class="source-line-no">7123</span><span id="line-7123"> CONF.setInt("hbase.rowlock.wait.duration", 1000);</span>
<span class="source-line-no">7124</span><span id="line-7124"> region = initHRegion(tableName, a, c, method, CONF, false, fam1);</span>
<span class="source-line-no">7125</span><span id="line-7125"></span>
<span class="source-line-no">7126</span><span id="line-7126"> Mutation[] mutations = new Mutation[] {</span>
<span class="source-line-no">7127</span><span id="line-7127"> new Put(a).add(CellBuilderFactory.create(CellBuilderType.SHALLOW_COPY).setRow(a)</span>
<span class="source-line-no">7128</span><span id="line-7128"> .setFamily(fam1).setTimestamp(HConstants.LATEST_TIMESTAMP).setType(Cell.Type.Put).build()),</span>
<span class="source-line-no">7129</span><span id="line-7129"> // this is outside the region boundary</span>
<span class="source-line-no">7130</span><span id="line-7130"> new Put(c).add(CellBuilderFactory.create(CellBuilderType.SHALLOW_COPY).setRow(c)</span>
<span class="source-line-no">7131</span><span id="line-7131"> .setFamily(fam1).setTimestamp(HConstants.LATEST_TIMESTAMP).setType(Type.Put).build()),</span>
<span class="source-line-no">7132</span><span id="line-7132"> new Put(b)</span>
<span class="source-line-no">7133</span><span id="line-7133"> .add(CellBuilderFactory.create(CellBuilderType.SHALLOW_COPY).setRow(b).setFamily(fam1)</span>
<span class="source-line-no">7134</span><span id="line-7134"> .setTimestamp(HConstants.LATEST_TIMESTAMP).setType(Cell.Type.Put).build()) };</span>
<span class="source-line-no">7135</span><span id="line-7135"></span>
<span class="source-line-no">7136</span><span id="line-7136"> OperationStatus[] status = region.batchMutate(mutations);</span>
<span class="source-line-no">7137</span><span id="line-7137"> assertEquals(OperationStatusCode.SUCCESS, status[0].getOperationStatusCode());</span>
<span class="source-line-no">7138</span><span id="line-7138"> assertEquals(OperationStatusCode.SANITY_CHECK_FAILURE, status[1].getOperationStatusCode());</span>
<span class="source-line-no">7139</span><span id="line-7139"> assertEquals(OperationStatusCode.SUCCESS, status[2].getOperationStatusCode());</span>
<span class="source-line-no">7140</span><span id="line-7140"></span>
<span class="source-line-no">7141</span><span id="line-7141"> // test with a row lock held for a long time</span>
<span class="source-line-no">7142</span><span id="line-7142"> final CountDownLatch obtainedRowLock = new CountDownLatch(1);</span>
<span class="source-line-no">7143</span><span id="line-7143"> ExecutorService exec = Executors.newFixedThreadPool(2);</span>
<span class="source-line-no">7144</span><span id="line-7144"> Future&lt;Void&gt; f1 = exec.submit(new Callable&lt;Void&gt;() {</span>
<span class="source-line-no">7145</span><span id="line-7145"> @Override</span>
<span class="source-line-no">7146</span><span id="line-7146"> public Void call() throws Exception {</span>
<span class="source-line-no">7147</span><span id="line-7147"> LOG.info("Acquiring row lock");</span>
<span class="source-line-no">7148</span><span id="line-7148"> RowLock rl = region.getRowLock(b);</span>
<span class="source-line-no">7149</span><span id="line-7149"> obtainedRowLock.countDown();</span>
<span class="source-line-no">7150</span><span id="line-7150"> LOG.info("Waiting for 5 seconds before releasing lock");</span>
<span class="source-line-no">7151</span><span id="line-7151"> Threads.sleep(5000);</span>
<span class="source-line-no">7152</span><span id="line-7152"> LOG.info("Releasing row lock");</span>
<span class="source-line-no">7153</span><span id="line-7153"> rl.release();</span>
<span class="source-line-no">7154</span><span id="line-7154"> return null;</span>
<span class="source-line-no">7155</span><span id="line-7155"> }</span>
<span class="source-line-no">7156</span><span id="line-7156"> });</span>
<span class="source-line-no">7157</span><span id="line-7157"> obtainedRowLock.await(30, TimeUnit.SECONDS);</span>
<span class="source-line-no">7158</span><span id="line-7158"></span>
<span class="source-line-no">7159</span><span id="line-7159"> Future&lt;Void&gt; f2 = exec.submit(new Callable&lt;Void&gt;() {</span>
<span class="source-line-no">7160</span><span id="line-7160"> @Override</span>
<span class="source-line-no">7161</span><span id="line-7161"> public Void call() throws Exception {</span>
<span class="source-line-no">7162</span><span id="line-7162"> Mutation[] mutations = new Mutation[] {</span>
<span class="source-line-no">7163</span><span id="line-7163"> new Put(a)</span>
<span class="source-line-no">7164</span><span id="line-7164"> .add(CellBuilderFactory.create(CellBuilderType.SHALLOW_COPY).setRow(a).setFamily(fam1)</span>
<span class="source-line-no">7165</span><span id="line-7165"> .setTimestamp(HConstants.LATEST_TIMESTAMP).setType(Cell.Type.Put).build()),</span>
<span class="source-line-no">7166</span><span id="line-7166"> new Put(b)</span>
<span class="source-line-no">7167</span><span id="line-7167"> .add(CellBuilderFactory.create(CellBuilderType.SHALLOW_COPY).setRow(b).setFamily(fam1)</span>
<span class="source-line-no">7168</span><span id="line-7168"> .setTimestamp(HConstants.LATEST_TIMESTAMP).setType(Cell.Type.Put).build()), };</span>
<span class="source-line-no">7169</span><span id="line-7169"></span>
<span class="source-line-no">7170</span><span id="line-7170"> // this will wait for the row lock, and it will eventually succeed</span>
<span class="source-line-no">7171</span><span id="line-7171"> OperationStatus[] status = region.batchMutate(mutations);</span>
<span class="source-line-no">7172</span><span id="line-7172"> assertEquals(OperationStatusCode.SUCCESS, status[0].getOperationStatusCode());</span>
<span class="source-line-no">7173</span><span id="line-7173"> assertEquals(OperationStatusCode.SUCCESS, status[1].getOperationStatusCode());</span>
<span class="source-line-no">7174</span><span id="line-7174"> return null;</span>
<span class="source-line-no">7175</span><span id="line-7175"> }</span>
<span class="source-line-no">7176</span><span id="line-7176"> });</span>
<span class="source-line-no">7177</span><span id="line-7177"></span>
<span class="source-line-no">7178</span><span id="line-7178"> f1.get();</span>
<span class="source-line-no">7179</span><span id="line-7179"> f2.get();</span>
<span class="source-line-no">7180</span><span id="line-7180"></span>
<span class="source-line-no">7181</span><span id="line-7181"> CONF.setInt("hbase.rowlock.wait.duration", prevLockTimeout);</span>
<span class="source-line-no">7182</span><span id="line-7182"> }</span>
<span class="source-line-no">7183</span><span id="line-7183"></span>
<span class="source-line-no">7184</span><span id="line-7184"> @Test</span>
<span class="source-line-no">7185</span><span id="line-7185"> public void testBatchMutateWithZeroRowLockWait() throws Exception {</span>
<span class="source-line-no">7186</span><span id="line-7186"> final byte[] a = Bytes.toBytes("a");</span>
<span class="source-line-no">7187</span><span id="line-7187"> final byte[] b = Bytes.toBytes("b");</span>
<span class="source-line-no">7188</span><span id="line-7188"> final byte[] c = Bytes.toBytes("c"); // exclusive</span>
<span class="source-line-no">7189</span><span id="line-7189"></span>
<span class="source-line-no">7190</span><span id="line-7190"> Configuration conf = new Configuration(CONF);</span>
<span class="source-line-no">7191</span><span id="line-7191"> conf.setInt("hbase.rowlock.wait.duration", 0);</span>
<span class="source-line-no">7192</span><span id="line-7192"> final RegionInfo hri =</span>
<span class="source-line-no">7193</span><span id="line-7193"> RegionInfoBuilder.newBuilder(tableName).setStartKey(a).setEndKey(c).build();</span>
<span class="source-line-no">7194</span><span id="line-7194"> final TableDescriptor htd = TableDescriptorBuilder.newBuilder(tableName)</span>
<span class="source-line-no">7195</span><span id="line-7195"> .setColumnFamily(ColumnFamilyDescriptorBuilder.of(fam1)).build();</span>
<span class="source-line-no">7196</span><span id="line-7196"> region = HRegion.createHRegion(hri, TEST_UTIL.getDataTestDir(), conf, htd,</span>
<span class="source-line-no">7197</span><span id="line-7197"> HBaseTestingUtil.createWal(conf, TEST_UTIL.getDataTestDirOnTestFS(method + ".log"), hri));</span>
<span class="source-line-no">7198</span><span id="line-7198"></span>
<span class="source-line-no">7199</span><span id="line-7199"> Mutation[] mutations = new Mutation[] {</span>
<span class="source-line-no">7200</span><span id="line-7200"> new Put(a).add(CellBuilderFactory.create(CellBuilderType.SHALLOW_COPY).setRow(a)</span>
<span class="source-line-no">7201</span><span id="line-7201"> .setFamily(fam1).setTimestamp(HConstants.LATEST_TIMESTAMP).setType(Cell.Type.Put).build()),</span>
<span class="source-line-no">7202</span><span id="line-7202"> new Put(b)</span>
<span class="source-line-no">7203</span><span id="line-7203"> .add(CellBuilderFactory.create(CellBuilderType.SHALLOW_COPY).setRow(b).setFamily(fam1)</span>
<span class="source-line-no">7204</span><span id="line-7204"> .setTimestamp(HConstants.LATEST_TIMESTAMP).setType(Cell.Type.Put).build()) };</span>
<span class="source-line-no">7205</span><span id="line-7205"></span>
<span class="source-line-no">7206</span><span id="line-7206"> OperationStatus[] status = region.batchMutate(mutations);</span>
<span class="source-line-no">7207</span><span id="line-7207"> assertEquals(OperationStatusCode.SUCCESS, status[0].getOperationStatusCode());</span>
<span class="source-line-no">7208</span><span id="line-7208"> assertEquals(OperationStatusCode.SUCCESS, status[1].getOperationStatusCode());</span>
<span class="source-line-no">7209</span><span id="line-7209"></span>
<span class="source-line-no">7210</span><span id="line-7210"> // test with a row lock held for a long time</span>
<span class="source-line-no">7211</span><span id="line-7211"> final CountDownLatch obtainedRowLock = new CountDownLatch(1);</span>
<span class="source-line-no">7212</span><span id="line-7212"> ExecutorService exec = Executors.newFixedThreadPool(2);</span>
<span class="source-line-no">7213</span><span id="line-7213"> Future&lt;Void&gt; f1 = exec.submit(new Callable&lt;Void&gt;() {</span>
<span class="source-line-no">7214</span><span id="line-7214"> @Override</span>
<span class="source-line-no">7215</span><span id="line-7215"> public Void call() throws Exception {</span>
<span class="source-line-no">7216</span><span id="line-7216"> LOG.info("Acquiring row lock");</span>
<span class="source-line-no">7217</span><span id="line-7217"> RowLock rl = region.getRowLock(b);</span>
<span class="source-line-no">7218</span><span id="line-7218"> obtainedRowLock.countDown();</span>
<span class="source-line-no">7219</span><span id="line-7219"> LOG.info("Waiting for 5 seconds before releasing lock");</span>
<span class="source-line-no">7220</span><span id="line-7220"> Threads.sleep(5000);</span>
<span class="source-line-no">7221</span><span id="line-7221"> LOG.info("Releasing row lock");</span>
<span class="source-line-no">7222</span><span id="line-7222"> rl.release();</span>
<span class="source-line-no">7223</span><span id="line-7223"> return null;</span>
<span class="source-line-no">7224</span><span id="line-7224"> }</span>
<span class="source-line-no">7225</span><span id="line-7225"> });</span>
<span class="source-line-no">7226</span><span id="line-7226"> obtainedRowLock.await(30, TimeUnit.SECONDS);</span>
<span class="source-line-no">7227</span><span id="line-7227"></span>
<span class="source-line-no">7228</span><span id="line-7228"> Future&lt;Void&gt; f2 = exec.submit(new Callable&lt;Void&gt;() {</span>
<span class="source-line-no">7229</span><span id="line-7229"> @Override</span>
<span class="source-line-no">7230</span><span id="line-7230"> public Void call() throws Exception {</span>
<span class="source-line-no">7231</span><span id="line-7231"> Mutation[] mutations = new Mutation[] {</span>
<span class="source-line-no">7232</span><span id="line-7232"> new Put(a)</span>
<span class="source-line-no">7233</span><span id="line-7233"> .add(CellBuilderFactory.create(CellBuilderType.SHALLOW_COPY).setRow(a).setFamily(fam1)</span>
<span class="source-line-no">7234</span><span id="line-7234"> .setTimestamp(HConstants.LATEST_TIMESTAMP).setType(Cell.Type.Put).build()),</span>
<span class="source-line-no">7235</span><span id="line-7235"> new Put(b)</span>
<span class="source-line-no">7236</span><span id="line-7236"> .add(CellBuilderFactory.create(CellBuilderType.SHALLOW_COPY).setRow(b).setFamily(fam1)</span>
<span class="source-line-no">7237</span><span id="line-7237"> .setTimestamp(HConstants.LATEST_TIMESTAMP).setType(Cell.Type.Put).build()), };</span>
<span class="source-line-no">7238</span><span id="line-7238"> // when handling row b we are going to spin on the failure to get the row lock</span>
<span class="source-line-no">7239</span><span id="line-7239"> // until the lock above is released, but we will still succeed so long as that</span>
<span class="source-line-no">7240</span><span id="line-7240"> // takes less time then the test time out.</span>
<span class="source-line-no">7241</span><span id="line-7241"> OperationStatus[] status = region.batchMutate(mutations);</span>
<span class="source-line-no">7242</span><span id="line-7242"> assertEquals(OperationStatusCode.SUCCESS, status[0].getOperationStatusCode());</span>
<span class="source-line-no">7243</span><span id="line-7243"> assertEquals(OperationStatusCode.SUCCESS, status[1].getOperationStatusCode());</span>
<span class="source-line-no">7244</span><span id="line-7244"> return null;</span>
<span class="source-line-no">7245</span><span id="line-7245"> }</span>
<span class="source-line-no">7246</span><span id="line-7246"> });</span>
<span class="source-line-no">7247</span><span id="line-7247"></span>
<span class="source-line-no">7248</span><span id="line-7248"> f1.get();</span>
<span class="source-line-no">7249</span><span id="line-7249"> f2.get();</span>
<span class="source-line-no">7250</span><span id="line-7250"> }</span>
<span class="source-line-no">7251</span><span id="line-7251"></span>
<span class="source-line-no">7252</span><span id="line-7252"> @Test</span>
<span class="source-line-no">7253</span><span id="line-7253"> public void testCheckAndRowMutateTimestampsAreMonotonic() throws IOException {</span>
<span class="source-line-no">7254</span><span id="line-7254"> region = initHRegion(tableName, method, CONF, fam1);</span>
<span class="source-line-no">7255</span><span id="line-7255"> ManualEnvironmentEdge edge = new ManualEnvironmentEdge();</span>
<span class="source-line-no">7256</span><span id="line-7256"> EnvironmentEdgeManager.injectEdge(edge);</span>
<span class="source-line-no">7257</span><span id="line-7257"></span>
<span class="source-line-no">7258</span><span id="line-7258"> edge.setValue(10);</span>
<span class="source-line-no">7259</span><span id="line-7259"> Put p = new Put(row);</span>
<span class="source-line-no">7260</span><span id="line-7260"> p.setDurability(Durability.SKIP_WAL);</span>
<span class="source-line-no">7261</span><span id="line-7261"> p.addColumn(fam1, qual1, qual1);</span>
<span class="source-line-no">7262</span><span id="line-7262"> region.put(p);</span>
<span class="source-line-no">7263</span><span id="line-7263"></span>
<span class="source-line-no">7264</span><span id="line-7264"> Result result = region.get(new Get(row));</span>
<span class="source-line-no">7265</span><span id="line-7265"> Cell c = result.getColumnLatestCell(fam1, qual1);</span>
<span class="source-line-no">7266</span><span id="line-7266"> assertNotNull(c);</span>
<span class="source-line-no">7267</span><span id="line-7267"> assertEquals(10L, c.getTimestamp());</span>
<span class="source-line-no">7268</span><span id="line-7268"></span>
<span class="source-line-no">7269</span><span id="line-7269"> edge.setValue(1); // clock goes back</span>
<span class="source-line-no">7270</span><span id="line-7270"> p = new Put(row);</span>
<span class="source-line-no">7271</span><span id="line-7271"> p.setDurability(Durability.SKIP_WAL);</span>
<span class="source-line-no">7272</span><span id="line-7272"> p.addColumn(fam1, qual1, qual2);</span>
<span class="source-line-no">7273</span><span id="line-7273"> RowMutations rm = new RowMutations(row);</span>
<span class="source-line-no">7274</span><span id="line-7274"> rm.add(p);</span>
<span class="source-line-no">7275</span><span id="line-7275"> assertTrue(region.checkAndRowMutate(row, fam1, qual1, CompareOperator.EQUAL,</span>
<span class="source-line-no">7276</span><span id="line-7276"> new BinaryComparator(qual1), rm));</span>
<span class="source-line-no">7277</span><span id="line-7277"> result = region.get(new Get(row));</span>
<span class="source-line-no">7278</span><span id="line-7278"> c = result.getColumnLatestCell(fam1, qual1);</span>
<span class="source-line-no">7279</span><span id="line-7279"> assertEquals(10L, c.getTimestamp());</span>
<span class="source-line-no">7280</span><span id="line-7280"> LOG.info(</span>
<span class="source-line-no">7281</span><span id="line-7281"> "c value " + Bytes.toStringBinary(c.getValueArray(), c.getValueOffset(), c.getValueLength()));</span>
<span class="source-line-no">7282</span><span id="line-7282"></span>
<span class="source-line-no">7283</span><span id="line-7283"> assertTrue(Bytes.equals(c.getValueArray(), c.getValueOffset(), c.getValueLength(), qual2, 0,</span>
<span class="source-line-no">7284</span><span id="line-7284"> qual2.length));</span>
<span class="source-line-no">7285</span><span id="line-7285"> }</span>
<span class="source-line-no">7286</span><span id="line-7286"></span>
<span class="source-line-no">7287</span><span id="line-7287"> private HRegion initHRegion(TableName tableName, String callingMethod, byte[]... families)</span>
<span class="source-line-no">7288</span><span id="line-7288"> throws IOException {</span>
<span class="source-line-no">7289</span><span id="line-7289"> return initHRegion(tableName, callingMethod, HBaseConfiguration.create(), families);</span>
<span class="source-line-no">7290</span><span id="line-7290"> }</span>
<span class="source-line-no">7291</span><span id="line-7291"></span>
<span class="source-line-no">7292</span><span id="line-7292"> /**</span>
<span class="source-line-no">7293</span><span id="line-7293"> * HBASE-16429 Make sure no stuck if roll writer when ring buffer is filled with appends</span>
<span class="source-line-no">7294</span><span id="line-7294"> * @throws IOException if IO error occurred during test</span>
<span class="source-line-no">7295</span><span id="line-7295"> */</span>
<span class="source-line-no">7296</span><span id="line-7296"> @Test</span>
<span class="source-line-no">7297</span><span id="line-7297"> public void testWritesWhileRollWriter() throws IOException {</span>
<span class="source-line-no">7298</span><span id="line-7298"> int testCount = 10;</span>
<span class="source-line-no">7299</span><span id="line-7299"> int numRows = 1024;</span>
<span class="source-line-no">7300</span><span id="line-7300"> int numFamilies = 2;</span>
<span class="source-line-no">7301</span><span id="line-7301"> int numQualifiers = 2;</span>
<span class="source-line-no">7302</span><span id="line-7302"> final byte[][] families = new byte[numFamilies][];</span>
<span class="source-line-no">7303</span><span id="line-7303"> for (int i = 0; i &lt; numFamilies; i++) {</span>
<span class="source-line-no">7304</span><span id="line-7304"> families[i] = Bytes.toBytes("family" + i);</span>
<span class="source-line-no">7305</span><span id="line-7305"> }</span>
<span class="source-line-no">7306</span><span id="line-7306"> final byte[][] qualifiers = new byte[numQualifiers][];</span>
<span class="source-line-no">7307</span><span id="line-7307"> for (int i = 0; i &lt; numQualifiers; i++) {</span>
<span class="source-line-no">7308</span><span id="line-7308"> qualifiers[i] = Bytes.toBytes("qual" + i);</span>
<span class="source-line-no">7309</span><span id="line-7309"> }</span>
<span class="source-line-no">7310</span><span id="line-7310"></span>
<span class="source-line-no">7311</span><span id="line-7311"> CONF.setInt("hbase.regionserver.wal.disruptor.event.count", 2);</span>
<span class="source-line-no">7312</span><span id="line-7312"> this.region = initHRegion(tableName, method, CONF, families);</span>
<span class="source-line-no">7313</span><span id="line-7313"> try {</span>
<span class="source-line-no">7314</span><span id="line-7314"> List&lt;Thread&gt; threads = new ArrayList&lt;&gt;();</span>
<span class="source-line-no">7315</span><span id="line-7315"> for (int i = 0; i &lt; numRows; i++) {</span>
<span class="source-line-no">7316</span><span id="line-7316"> final int count = i;</span>
<span class="source-line-no">7317</span><span id="line-7317"> Thread t = new Thread(new Runnable() {</span>
<span class="source-line-no">7318</span><span id="line-7318"></span>
<span class="source-line-no">7319</span><span id="line-7319"> @Override</span>
<span class="source-line-no">7320</span><span id="line-7320"> public void run() {</span>
<span class="source-line-no">7321</span><span id="line-7321"> byte[] row = Bytes.toBytes("row" + count);</span>
<span class="source-line-no">7322</span><span id="line-7322"> Put put = new Put(row);</span>
<span class="source-line-no">7323</span><span id="line-7323"> put.setDurability(Durability.SYNC_WAL);</span>
<span class="source-line-no">7324</span><span id="line-7324"> byte[] value = Bytes.toBytes(String.valueOf(count));</span>
<span class="source-line-no">7325</span><span id="line-7325"> for (byte[] family : families) {</span>
<span class="source-line-no">7326</span><span id="line-7326"> for (byte[] qualifier : qualifiers) {</span>
<span class="source-line-no">7327</span><span id="line-7327"> put.addColumn(family, qualifier, count, value);</span>
<span class="source-line-no">7328</span><span id="line-7328"> }</span>
<span class="source-line-no">7329</span><span id="line-7329"> }</span>
<span class="source-line-no">7330</span><span id="line-7330"> try {</span>
<span class="source-line-no">7331</span><span id="line-7331"> region.put(put);</span>
<span class="source-line-no">7332</span><span id="line-7332"> } catch (IOException e) {</span>
<span class="source-line-no">7333</span><span id="line-7333"> throw new RuntimeException(e);</span>
<span class="source-line-no">7334</span><span id="line-7334"> }</span>
<span class="source-line-no">7335</span><span id="line-7335"> }</span>
<span class="source-line-no">7336</span><span id="line-7336"> });</span>
<span class="source-line-no">7337</span><span id="line-7337"> threads.add(t);</span>
<span class="source-line-no">7338</span><span id="line-7338"> }</span>
<span class="source-line-no">7339</span><span id="line-7339"> for (Thread t : threads) {</span>
<span class="source-line-no">7340</span><span id="line-7340"> t.start();</span>
<span class="source-line-no">7341</span><span id="line-7341"> }</span>
<span class="source-line-no">7342</span><span id="line-7342"></span>
<span class="source-line-no">7343</span><span id="line-7343"> for (int i = 0; i &lt; testCount; i++) {</span>
<span class="source-line-no">7344</span><span id="line-7344"> region.getWAL().rollWriter();</span>
<span class="source-line-no">7345</span><span id="line-7345"> Thread.yield();</span>
<span class="source-line-no">7346</span><span id="line-7346"> }</span>
<span class="source-line-no">7347</span><span id="line-7347"> } finally {</span>
<span class="source-line-no">7348</span><span id="line-7348"> try {</span>
<span class="source-line-no">7349</span><span id="line-7349"> HBaseTestingUtil.closeRegionAndWAL(this.region);</span>
<span class="source-line-no">7350</span><span id="line-7350"> CONF.setInt("hbase.regionserver.wal.disruptor.event.count", 16 * 1024);</span>
<span class="source-line-no">7351</span><span id="line-7351"> } catch (DroppedSnapshotException dse) {</span>
<span class="source-line-no">7352</span><span id="line-7352"> // We could get this on way out because we interrupt the background flusher and it could</span>
<span class="source-line-no">7353</span><span id="line-7353"> // fail anywhere causing a DSE over in the background flusher... only it is not properly</span>
<span class="source-line-no">7354</span><span id="line-7354"> // dealt with so could still be memory hanging out when we get to here -- memory we can't</span>
<span class="source-line-no">7355</span><span id="line-7355"> // flush because the accounting is 'off' since original DSE.</span>
<span class="source-line-no">7356</span><span id="line-7356"> }</span>
<span class="source-line-no">7357</span><span id="line-7357"> this.region = null;</span>
<span class="source-line-no">7358</span><span id="line-7358"> }</span>
<span class="source-line-no">7359</span><span id="line-7359"> }</span>
<span class="source-line-no">7360</span><span id="line-7360"></span>
<span class="source-line-no">7361</span><span id="line-7361"> @Test</span>
<span class="source-line-no">7362</span><span id="line-7362"> public void testMutateRow() throws Exception {</span>
<span class="source-line-no">7363</span><span id="line-7363"> final byte[] row = Bytes.toBytes("row");</span>
<span class="source-line-no">7364</span><span id="line-7364"> final byte[] q1 = Bytes.toBytes("q1");</span>
<span class="source-line-no">7365</span><span id="line-7365"> final byte[] q2 = Bytes.toBytes("q2");</span>
<span class="source-line-no">7366</span><span id="line-7366"> final byte[] q3 = Bytes.toBytes("q3");</span>
<span class="source-line-no">7367</span><span id="line-7367"> final byte[] q4 = Bytes.toBytes("q4");</span>
<span class="source-line-no">7368</span><span id="line-7368"> final String v1 = "v1";</span>
<span class="source-line-no">7369</span><span id="line-7369"></span>
<span class="source-line-no">7370</span><span id="line-7370"> region = initHRegion(tableName, method, CONF, fam1);</span>
<span class="source-line-no">7371</span><span id="line-7371"></span>
<span class="source-line-no">7372</span><span id="line-7372"> // Initial values</span>
<span class="source-line-no">7373</span><span id="line-7373"> region</span>
<span class="source-line-no">7374</span><span id="line-7374"> .batchMutate(new Mutation[] { new Put(row).addColumn(fam1, q2, Bytes.toBytes("toBeDeleted")),</span>
<span class="source-line-no">7375</span><span id="line-7375"> new Put(row).addColumn(fam1, q3, Bytes.toBytes(5L)),</span>
<span class="source-line-no">7376</span><span id="line-7376"> new Put(row).addColumn(fam1, q4, Bytes.toBytes("a")), });</span>
<span class="source-line-no">7377</span><span id="line-7377"></span>
<span class="source-line-no">7378</span><span id="line-7378"> // Do mutateRow</span>
<span class="source-line-no">7379</span><span id="line-7379"> Result result = region.mutateRow(</span>
<span class="source-line-no">7380</span><span id="line-7380"> new RowMutations(row).add(Arrays.asList(new Put(row).addColumn(fam1, q1, Bytes.toBytes(v1)),</span>
<span class="source-line-no">7381</span><span id="line-7381"> new Delete(row).addColumns(fam1, q2), new Increment(row).addColumn(fam1, q3, 1),</span>
<span class="source-line-no">7382</span><span id="line-7382"> new Append(row).addColumn(fam1, q4, Bytes.toBytes("b")))));</span>
<span class="source-line-no">7383</span><span id="line-7383"></span>
<span class="source-line-no">7384</span><span id="line-7384"> assertNotNull(result);</span>
<span class="source-line-no">7385</span><span id="line-7385"> assertEquals(6L, Bytes.toLong(result.getValue(fam1, q3)));</span>
<span class="source-line-no">7386</span><span id="line-7386"> assertEquals("ab", Bytes.toString(result.getValue(fam1, q4)));</span>
<span class="source-line-no">7387</span><span id="line-7387"></span>
<span class="source-line-no">7388</span><span id="line-7388"> // Verify the value</span>
<span class="source-line-no">7389</span><span id="line-7389"> result = region.get(new Get(row));</span>
<span class="source-line-no">7390</span><span id="line-7390"> assertEquals(v1, Bytes.toString(result.getValue(fam1, q1)));</span>
<span class="source-line-no">7391</span><span id="line-7391"> assertNull(result.getValue(fam1, q2));</span>
<span class="source-line-no">7392</span><span id="line-7392"> assertEquals(6L, Bytes.toLong(result.getValue(fam1, q3)));</span>
<span class="source-line-no">7393</span><span id="line-7393"> assertEquals("ab", Bytes.toString(result.getValue(fam1, q4)));</span>
<span class="source-line-no">7394</span><span id="line-7394"> }</span>
<span class="source-line-no">7395</span><span id="line-7395"></span>
<span class="source-line-no">7396</span><span id="line-7396"> @Test</span>
<span class="source-line-no">7397</span><span id="line-7397"> public void testMutateRowInParallel() throws Exception {</span>
<span class="source-line-no">7398</span><span id="line-7398"> final int numReaderThreads = 100;</span>
<span class="source-line-no">7399</span><span id="line-7399"> final CountDownLatch latch = new CountDownLatch(numReaderThreads);</span>
<span class="source-line-no">7400</span><span id="line-7400"></span>
<span class="source-line-no">7401</span><span id="line-7401"> final byte[] row = Bytes.toBytes("row");</span>
<span class="source-line-no">7402</span><span id="line-7402"> final byte[] q1 = Bytes.toBytes("q1");</span>
<span class="source-line-no">7403</span><span id="line-7403"> final byte[] q2 = Bytes.toBytes("q2");</span>
<span class="source-line-no">7404</span><span id="line-7404"> final byte[] q3 = Bytes.toBytes("q3");</span>
<span class="source-line-no">7405</span><span id="line-7405"> final byte[] q4 = Bytes.toBytes("q4");</span>
<span class="source-line-no">7406</span><span id="line-7406"> final String v1 = "v1";</span>
<span class="source-line-no">7407</span><span id="line-7407"> final String v2 = "v2";</span>
<span class="source-line-no">7408</span><span id="line-7408"></span>
<span class="source-line-no">7409</span><span id="line-7409"> // We need to ensure the timestamp of the delete operation is more than the previous one</span>
<span class="source-line-no">7410</span><span id="line-7410"> final AtomicLong deleteTimestamp = new AtomicLong();</span>
<span class="source-line-no">7411</span><span id="line-7411"></span>
<span class="source-line-no">7412</span><span id="line-7412"> region = initHRegion(tableName, method, CONF, fam1);</span>
<span class="source-line-no">7413</span><span id="line-7413"></span>
<span class="source-line-no">7414</span><span id="line-7414"> // Initial values</span>
<span class="source-line-no">7415</span><span id="line-7415"> region.batchMutate(new Mutation[] { new Put(row).addColumn(fam1, q1, Bytes.toBytes(v1))</span>
<span class="source-line-no">7416</span><span id="line-7416"> .addColumn(fam1, q2, deleteTimestamp.getAndIncrement(), Bytes.toBytes(v2))</span>
<span class="source-line-no">7417</span><span id="line-7417"> .addColumn(fam1, q3, Bytes.toBytes(1L)).addColumn(fam1, q4, Bytes.toBytes("a")) });</span>
<span class="source-line-no">7418</span><span id="line-7418"></span>
<span class="source-line-no">7419</span><span id="line-7419"> final AtomicReference&lt;AssertionError&gt; assertionError = new AtomicReference&lt;&gt;();</span>
<span class="source-line-no">7420</span><span id="line-7420"></span>
<span class="source-line-no">7421</span><span id="line-7421"> // Writer thread</span>
<span class="source-line-no">7422</span><span id="line-7422"> Thread writerThread = new Thread(() -&gt; {</span>
<span class="source-line-no">7423</span><span id="line-7423"> try {</span>
<span class="source-line-no">7424</span><span id="line-7424"> while (true) {</span>
<span class="source-line-no">7425</span><span id="line-7425"> // If all the reader threads finish, then stop the writer thread</span>
<span class="source-line-no">7426</span><span id="line-7426"> if (latch.await(0, TimeUnit.MILLISECONDS)) {</span>
<span class="source-line-no">7427</span><span id="line-7427"> return;</span>
<span class="source-line-no">7428</span><span id="line-7428"> }</span>
<span class="source-line-no">7429</span><span id="line-7429"></span>
<span class="source-line-no">7430</span><span id="line-7430"> // Execute the mutations. This should be done atomically</span>
<span class="source-line-no">7431</span><span id="line-7431"> region.mutateRow(new RowMutations(row)</span>
<span class="source-line-no">7432</span><span id="line-7432"> .add(Arrays.asList(new Put(row).addColumn(fam1, q1, Bytes.toBytes(v2)),</span>
<span class="source-line-no">7433</span><span id="line-7433"> new Delete(row).addColumns(fam1, q2, deleteTimestamp.getAndIncrement()),</span>
<span class="source-line-no">7434</span><span id="line-7434"> new Increment(row).addColumn(fam1, q3, 1L),</span>
<span class="source-line-no">7435</span><span id="line-7435"> new Append(row).addColumn(fam1, q4, Bytes.toBytes("b")))));</span>
<span class="source-line-no">7436</span><span id="line-7436"></span>
<span class="source-line-no">7437</span><span id="line-7437"> // We need to ensure the timestamps of the Increment/Append operations are more than the</span>
<span class="source-line-no">7438</span><span id="line-7438"> // previous ones</span>
<span class="source-line-no">7439</span><span id="line-7439"> Result result = region.get(new Get(row).addColumn(fam1, q3).addColumn(fam1, q4));</span>
<span class="source-line-no">7440</span><span id="line-7440"> long tsIncrement = result.getColumnLatestCell(fam1, q3).getTimestamp();</span>
<span class="source-line-no">7441</span><span id="line-7441"> long tsAppend = result.getColumnLatestCell(fam1, q4).getTimestamp();</span>
<span class="source-line-no">7442</span><span id="line-7442"></span>
<span class="source-line-no">7443</span><span id="line-7443"> // Put the initial values</span>
<span class="source-line-no">7444</span><span id="line-7444"> region.batchMutate(new Mutation[] { new Put(row).addColumn(fam1, q1, Bytes.toBytes(v1))</span>
<span class="source-line-no">7445</span><span id="line-7445"> .addColumn(fam1, q2, deleteTimestamp.getAndIncrement(), Bytes.toBytes(v2))</span>
<span class="source-line-no">7446</span><span id="line-7446"> .addColumn(fam1, q3, tsIncrement + 1, Bytes.toBytes(1L))</span>
<span class="source-line-no">7447</span><span id="line-7447"> .addColumn(fam1, q4, tsAppend + 1, Bytes.toBytes("a")) });</span>
<span class="source-line-no">7448</span><span id="line-7448"> }</span>
<span class="source-line-no">7449</span><span id="line-7449"> } catch (Exception e) {</span>
<span class="source-line-no">7450</span><span id="line-7450"> assertionError.set(new AssertionError(e));</span>
<span class="source-line-no">7451</span><span id="line-7451"> }</span>
<span class="source-line-no">7452</span><span id="line-7452"> });</span>
<span class="source-line-no">7453</span><span id="line-7453"> writerThread.start();</span>
<span class="source-line-no">7454</span><span id="line-7454"></span>
<span class="source-line-no">7455</span><span id="line-7455"> // Reader threads</span>
<span class="source-line-no">7456</span><span id="line-7456"> for (int i = 0; i &lt; numReaderThreads; i++) {</span>
<span class="source-line-no">7457</span><span id="line-7457"> new Thread(() -&gt; {</span>
<span class="source-line-no">7458</span><span id="line-7458"> try {</span>
<span class="source-line-no">7459</span><span id="line-7459"> for (int j = 0; j &lt; 10000; j++) {</span>
<span class="source-line-no">7460</span><span id="line-7460"> // Verify the values</span>
<span class="source-line-no">7461</span><span id="line-7461"> Result result = region.get(new Get(row));</span>
<span class="source-line-no">7462</span><span id="line-7462"></span>
<span class="source-line-no">7463</span><span id="line-7463"> // The values should be equals to either the initial values or the values after</span>
<span class="source-line-no">7464</span><span id="line-7464"> // executing the mutations</span>
<span class="source-line-no">7465</span><span id="line-7465"> String q1Value = Bytes.toString(result.getValue(fam1, q1));</span>
<span class="source-line-no">7466</span><span id="line-7466"> if (v1.equals(q1Value)) {</span>
<span class="source-line-no">7467</span><span id="line-7467"> assertEquals(v2, Bytes.toString(result.getValue(fam1, q2)));</span>
<span class="source-line-no">7468</span><span id="line-7468"> assertEquals(1L, Bytes.toLong(result.getValue(fam1, q3)));</span>
<span class="source-line-no">7469</span><span id="line-7469"> assertEquals("a", Bytes.toString(result.getValue(fam1, q4)));</span>
<span class="source-line-no">7470</span><span id="line-7470"> } else if (v2.equals(q1Value)) {</span>
<span class="source-line-no">7471</span><span id="line-7471"> assertNull(Bytes.toString(result.getValue(fam1, q2)));</span>
<span class="source-line-no">7472</span><span id="line-7472"> assertEquals(2L, Bytes.toLong(result.getValue(fam1, q3)));</span>
<span class="source-line-no">7473</span><span id="line-7473"> assertEquals("ab", Bytes.toString(result.getValue(fam1, q4)));</span>
<span class="source-line-no">7474</span><span id="line-7474"> } else {</span>
<span class="source-line-no">7475</span><span id="line-7475"> fail("the qualifier " + Bytes.toString(q1) + " should be " + v1 + " or " + v2</span>
<span class="source-line-no">7476</span><span id="line-7476"> + ", but " + q1Value);</span>
<span class="source-line-no">7477</span><span id="line-7477"> }</span>
<span class="source-line-no">7478</span><span id="line-7478"> }</span>
<span class="source-line-no">7479</span><span id="line-7479"> } catch (Exception e) {</span>
<span class="source-line-no">7480</span><span id="line-7480"> assertionError.set(new AssertionError(e));</span>
<span class="source-line-no">7481</span><span id="line-7481"> } catch (AssertionError e) {</span>
<span class="source-line-no">7482</span><span id="line-7482"> assertionError.set(e);</span>
<span class="source-line-no">7483</span><span id="line-7483"> }</span>
<span class="source-line-no">7484</span><span id="line-7484"></span>
<span class="source-line-no">7485</span><span id="line-7485"> latch.countDown();</span>
<span class="source-line-no">7486</span><span id="line-7486"> }).start();</span>
<span class="source-line-no">7487</span><span id="line-7487"> }</span>
<span class="source-line-no">7488</span><span id="line-7488"></span>
<span class="source-line-no">7489</span><span id="line-7489"> writerThread.join();</span>
<span class="source-line-no">7490</span><span id="line-7490"></span>
<span class="source-line-no">7491</span><span id="line-7491"> if (assertionError.get() != null) {</span>
<span class="source-line-no">7492</span><span id="line-7492"> throw assertionError.get();</span>
<span class="source-line-no">7493</span><span id="line-7493"> }</span>
<span class="source-line-no">7494</span><span id="line-7494"> }</span>
<span class="source-line-no">7495</span><span id="line-7495"></span>
<span class="source-line-no">7496</span><span id="line-7496"> @Test</span>
<span class="source-line-no">7497</span><span id="line-7497"> public void testMutateRow_WriteRequestCount() throws Exception {</span>
<span class="source-line-no">7498</span><span id="line-7498"> byte[] row1 = Bytes.toBytes("row1");</span>
<span class="source-line-no">7499</span><span id="line-7499"> byte[] fam1 = Bytes.toBytes("fam1");</span>
<span class="source-line-no">7500</span><span id="line-7500"> byte[] qf1 = Bytes.toBytes("qualifier");</span>
<span class="source-line-no">7501</span><span id="line-7501"> byte[] val1 = Bytes.toBytes("value1");</span>
<span class="source-line-no">7502</span><span id="line-7502"></span>
<span class="source-line-no">7503</span><span id="line-7503"> RowMutations rm = new RowMutations(row1);</span>
<span class="source-line-no">7504</span><span id="line-7504"> Put put = new Put(row1);</span>
<span class="source-line-no">7505</span><span id="line-7505"> put.addColumn(fam1, qf1, val1);</span>
<span class="source-line-no">7506</span><span id="line-7506"> rm.add(put);</span>
<span class="source-line-no">7507</span><span id="line-7507"></span>
<span class="source-line-no">7508</span><span id="line-7508"> this.region = initHRegion(tableName, method, CONF, fam1);</span>
<span class="source-line-no">7509</span><span id="line-7509"> long wrcBeforeMutate = this.region.writeRequestsCount.longValue();</span>
<span class="source-line-no">7510</span><span id="line-7510"> this.region.mutateRow(rm);</span>
<span class="source-line-no">7511</span><span id="line-7511"> long wrcAfterMutate = this.region.writeRequestsCount.longValue();</span>
<span class="source-line-no">7512</span><span id="line-7512"> Assert.assertEquals(wrcBeforeMutate + rm.getMutations().size(), wrcAfterMutate);</span>
<span class="source-line-no">7513</span><span id="line-7513"> }</span>
<span class="source-line-no">7514</span><span id="line-7514"></span>
<span class="source-line-no">7515</span><span id="line-7515"> @Test</span>
<span class="source-line-no">7516</span><span id="line-7516"> public void testBulkLoadReplicationEnabled() throws IOException {</span>
<span class="source-line-no">7517</span><span id="line-7517"> TEST_UTIL.getConfiguration().setBoolean(HConstants.REPLICATION_BULKLOAD_ENABLE_KEY, true);</span>
<span class="source-line-no">7518</span><span id="line-7518"> final ServerName serverName = ServerName.valueOf(name.getMethodName(), 100, 42);</span>
<span class="source-line-no">7519</span><span id="line-7519"> final RegionServerServices rss = spy(TEST_UTIL.createMockRegionServerService(serverName));</span>
<span class="source-line-no">7520</span><span id="line-7520"></span>
<span class="source-line-no">7521</span><span id="line-7521"> TableDescriptor tableDescriptor =</span>
<span class="source-line-no">7522</span><span id="line-7522"> TableDescriptorBuilder.newBuilder(TableName.valueOf(name.getMethodName()))</span>
<span class="source-line-no">7523</span><span id="line-7523"> .setColumnFamily(ColumnFamilyDescriptorBuilder.of(fam1)).build();</span>
<span class="source-line-no">7524</span><span id="line-7524"> RegionInfo hri = RegionInfoBuilder.newBuilder(tableDescriptor.getTableName()).build();</span>
<span class="source-line-no">7525</span><span id="line-7525"> region = HRegion.openHRegion(hri, tableDescriptor, rss.getWAL(hri),</span>
<span class="source-line-no">7526</span><span id="line-7526"> TEST_UTIL.getConfiguration(), rss, null);</span>
<span class="source-line-no">7527</span><span id="line-7527"></span>
<span class="source-line-no">7528</span><span id="line-7528"> assertTrue(region.conf.getBoolean(HConstants.REPLICATION_BULKLOAD_ENABLE_KEY, false));</span>
<span class="source-line-no">7529</span><span id="line-7529"> String plugins = region.conf.get(CoprocessorHost.REGION_COPROCESSOR_CONF_KEY, "");</span>
<span class="source-line-no">7530</span><span id="line-7530"> String replicationCoprocessorClass = ReplicationObserver.class.getCanonicalName();</span>
<span class="source-line-no">7531</span><span id="line-7531"> assertTrue(plugins.contains(replicationCoprocessorClass));</span>
<span class="source-line-no">7532</span><span id="line-7532"> assertTrue(region.getCoprocessorHost().getCoprocessors()</span>
<span class="source-line-no">7533</span><span id="line-7533"> .contains(ReplicationObserver.class.getSimpleName()));</span>
<span class="source-line-no">7534</span><span id="line-7534"> }</span>
<span class="source-line-no">7535</span><span id="line-7535"></span>
<span class="source-line-no">7536</span><span id="line-7536"> /**</span>
<span class="source-line-no">7537</span><span id="line-7537"> * The same as HRegion class, the only difference is that instantiateHStore will create a</span>
<span class="source-line-no">7538</span><span id="line-7538"> * different HStore - HStoreForTesting. [HBASE-8518]</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 static class HRegionForTesting extends HRegion {</span>
<span class="source-line-no">7541</span><span id="line-7541"></span>
<span class="source-line-no">7542</span><span id="line-7542"> public HRegionForTesting(final Path tableDir, final WAL wal, final FileSystem fs,</span>
<span class="source-line-no">7543</span><span id="line-7543"> final Configuration confParam, final RegionInfo regionInfo, final TableDescriptor htd,</span>
<span class="source-line-no">7544</span><span id="line-7544"> final RegionServerServices rsServices) {</span>
<span class="source-line-no">7545</span><span id="line-7545"> this(new HRegionFileSystem(confParam, fs, tableDir, regionInfo), wal, confParam, htd,</span>
<span class="source-line-no">7546</span><span id="line-7546"> rsServices);</span>
<span class="source-line-no">7547</span><span id="line-7547"> }</span>
<span class="source-line-no">7548</span><span id="line-7548"></span>
<span class="source-line-no">7549</span><span id="line-7549"> public HRegionForTesting(HRegionFileSystem fs, WAL wal, Configuration confParam,</span>
<span class="source-line-no">7550</span><span id="line-7550"> TableDescriptor htd, RegionServerServices rsServices) {</span>
<span class="source-line-no">7551</span><span id="line-7551"> super(fs, wal, confParam, htd, rsServices);</span>
<span class="source-line-no">7552</span><span id="line-7552"> }</span>
<span class="source-line-no">7553</span><span id="line-7553"></span>
<span class="source-line-no">7554</span><span id="line-7554"> /**</span>
<span class="source-line-no">7555</span><span id="line-7555"> * Create HStore instance.</span>
<span class="source-line-no">7556</span><span id="line-7556"> * @return If Mob is enabled, return HMobStore, otherwise return HStoreForTesting.</span>
<span class="source-line-no">7557</span><span id="line-7557"> */</span>
<span class="source-line-no">7558</span><span id="line-7558"> @Override</span>
<span class="source-line-no">7559</span><span id="line-7559"> protected HStore instantiateHStore(final ColumnFamilyDescriptor family, boolean warmup)</span>
<span class="source-line-no">7560</span><span id="line-7560"> throws IOException {</span>
<span class="source-line-no">7561</span><span id="line-7561"> if (family.isMobEnabled()) {</span>
<span class="source-line-no">7562</span><span id="line-7562"> if (HFile.getFormatVersion(this.conf) &lt; HFile.MIN_FORMAT_VERSION_WITH_TAGS) {</span>
<span class="source-line-no">7563</span><span id="line-7563"> throw new IOException("A minimum HFile version of " + HFile.MIN_FORMAT_VERSION_WITH_TAGS</span>
<span class="source-line-no">7564</span><span id="line-7564"> + " is required for MOB feature. Consider setting " + HFile.FORMAT_VERSION_KEY</span>
<span class="source-line-no">7565</span><span id="line-7565"> + " accordingly.");</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 HMobStore(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"> return new HStoreForTesting(this, family, this.conf, warmup);</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"></span>
<span class="source-line-no">7573</span><span id="line-7573"> /**</span>
<span class="source-line-no">7574</span><span id="line-7574"> * HStoreForTesting is merely the same as HStore, the difference is in the doCompaction method of</span>
<span class="source-line-no">7575</span><span id="line-7575"> * HStoreForTesting there is a checkpoint "hbase.hstore.compaction.complete" which doesn't let</span>
<span class="source-line-no">7576</span><span id="line-7576"> * hstore compaction complete. In the former edition, this config is set in HStore class inside</span>
<span class="source-line-no">7577</span><span id="line-7577"> * compact method, though this is just for testing, otherwise it doesn't do any help. In</span>
<span class="source-line-no">7578</span><span id="line-7578"> * HBASE-8518, we try to get rid of all "hbase.hstore.compaction.complete" config (except for</span>
<span class="source-line-no">7579</span><span id="line-7579"> * testing code).</span>
<span class="source-line-no">7580</span><span id="line-7580"> */</span>
<span class="source-line-no">7581</span><span id="line-7581"> public static class HStoreForTesting extends HStore {</span>
<span class="source-line-no">7582</span><span id="line-7582"></span>
<span class="source-line-no">7583</span><span id="line-7583"> protected HStoreForTesting(final HRegion region, final ColumnFamilyDescriptor family,</span>
<span class="source-line-no">7584</span><span id="line-7584"> final Configuration confParam, boolean warmup) throws IOException {</span>
<span class="source-line-no">7585</span><span id="line-7585"> super(region, family, confParam, warmup);</span>
<span class="source-line-no">7586</span><span id="line-7586"> }</span>
<span class="source-line-no">7587</span><span id="line-7587"></span>
<span class="source-line-no">7588</span><span id="line-7588"> @Override</span>
<span class="source-line-no">7589</span><span id="line-7589"> protected List&lt;HStoreFile&gt; doCompaction(CompactionRequestImpl cr,</span>
<span class="source-line-no">7590</span><span id="line-7590"> Collection&lt;HStoreFile&gt; filesToCompact, User user, long compactionStartTime,</span>
<span class="source-line-no">7591</span><span id="line-7591"> List&lt;Path&gt; newFiles) throws IOException {</span>
<span class="source-line-no">7592</span><span id="line-7592"> // let compaction incomplete.</span>
<span class="source-line-no">7593</span><span id="line-7593"> if (!this.conf.getBoolean("hbase.hstore.compaction.complete", true)) {</span>
<span class="source-line-no">7594</span><span id="line-7594"> LOG.warn("hbase.hstore.compaction.complete is set to false");</span>
<span class="source-line-no">7595</span><span id="line-7595"> List&lt;HStoreFile&gt; sfs = new ArrayList&lt;&gt;(newFiles.size());</span>
<span class="source-line-no">7596</span><span id="line-7596"> final boolean evictOnClose =</span>
<span class="source-line-no">7597</span><span id="line-7597"> getCacheConfig() != null ? getCacheConfig().shouldEvictOnClose() : true;</span>
<span class="source-line-no">7598</span><span id="line-7598"> for (Path newFile : newFiles) {</span>
<span class="source-line-no">7599</span><span id="line-7599"> // Create storefile around what we wrote with a reader on it.</span>
<span class="source-line-no">7600</span><span id="line-7600"> HStoreFile sf = storeEngine.createStoreFileAndReader(newFile);</span>
<span class="source-line-no">7601</span><span id="line-7601"> sf.closeStoreFile(evictOnClose);</span>
<span class="source-line-no">7602</span><span id="line-7602"> sfs.add(sf);</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 sfs;</span>
<span class="source-line-no">7605</span><span id="line-7605"> }</span>
<span class="source-line-no">7606</span><span id="line-7606"> return super.doCompaction(cr, filesToCompact, user, compactionStartTime, newFiles);</span>
<span class="source-line-no">7607</span><span id="line-7607"> }</span>
<span class="source-line-no">7608</span><span id="line-7608"> }</span>
<span class="source-line-no">7609</span><span id="line-7609"></span>
<span class="source-line-no">7610</span><span id="line-7610"> @Test</span>
<span class="source-line-no">7611</span><span id="line-7611"> public void testCloseNoInterrupt() throws Exception {</span>
<span class="source-line-no">7612</span><span id="line-7612"> byte[] cf1 = Bytes.toBytes("CF1");</span>
<span class="source-line-no">7613</span><span id="line-7613"> byte[][] families = { cf1 };</span>
<span class="source-line-no">7614</span><span id="line-7614"> final int SLEEP_TIME = 10 * 1000;</span>
<span class="source-line-no">7615</span><span id="line-7615"></span>
<span class="source-line-no">7616</span><span id="line-7616"> Configuration conf = new Configuration(CONF);</span>
<span class="source-line-no">7617</span><span id="line-7617"> // Disable close thread interrupt and server abort behavior</span>
<span class="source-line-no">7618</span><span id="line-7618"> conf.setBoolean(HRegion.CLOSE_WAIT_ABORT, false);</span>
<span class="source-line-no">7619</span><span id="line-7619"> conf.setInt(HRegion.CLOSE_WAIT_INTERVAL, 1000);</span>
<span class="source-line-no">7620</span><span id="line-7620"> region = initHRegion(tableName, method, conf, families);</span>
<span class="source-line-no">7621</span><span id="line-7621"></span>
<span class="source-line-no">7622</span><span id="line-7622"> final CountDownLatch latch = new CountDownLatch(1);</span>
<span class="source-line-no">7623</span><span id="line-7623"> final AtomicBoolean holderInterrupted = new AtomicBoolean();</span>
<span class="source-line-no">7624</span><span id="line-7624"> Thread holder = new Thread(new Runnable() {</span>
<span class="source-line-no">7625</span><span id="line-7625"> @Override</span>
<span class="source-line-no">7626</span><span id="line-7626"> public void run() {</span>
<span class="source-line-no">7627</span><span id="line-7627"> try {</span>
<span class="source-line-no">7628</span><span id="line-7628"> LOG.info("Starting region operation holder");</span>
<span class="source-line-no">7629</span><span id="line-7629"> region.startRegionOperation(Operation.SCAN);</span>
<span class="source-line-no">7630</span><span id="line-7630"> latch.countDown();</span>
<span class="source-line-no">7631</span><span id="line-7631"> try {</span>
<span class="source-line-no">7632</span><span id="line-7632"> Thread.sleep(SLEEP_TIME);</span>
<span class="source-line-no">7633</span><span id="line-7633"> } catch (InterruptedException e) {</span>
<span class="source-line-no">7634</span><span id="line-7634"> LOG.info("Interrupted");</span>
<span class="source-line-no">7635</span><span id="line-7635"> holderInterrupted.set(true);</span>
<span class="source-line-no">7636</span><span id="line-7636"> }</span>
<span class="source-line-no">7637</span><span id="line-7637"> } catch (Exception e) {</span>
<span class="source-line-no">7638</span><span id="line-7638"> throw new RuntimeException(e);</span>
<span class="source-line-no">7639</span><span id="line-7639"> } finally {</span>
<span class="source-line-no">7640</span><span id="line-7640"> try {</span>
<span class="source-line-no">7641</span><span id="line-7641"> region.closeRegionOperation();</span>
<span class="source-line-no">7642</span><span id="line-7642"> } catch (IOException e) {</span>
<span class="source-line-no">7643</span><span id="line-7643"> }</span>
<span class="source-line-no">7644</span><span id="line-7644"> LOG.info("Stopped region operation holder");</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"> });</span>
<span class="source-line-no">7648</span><span id="line-7648"></span>
<span class="source-line-no">7649</span><span id="line-7649"> holder.start();</span>
<span class="source-line-no">7650</span><span id="line-7650"> latch.await();</span>
<span class="source-line-no">7651</span><span id="line-7651"> HBaseTestingUtil.closeRegionAndWAL(region);</span>
<span class="source-line-no">7652</span><span id="line-7652"> region = null;</span>
<span class="source-line-no">7653</span><span id="line-7653"> holder.join();</span>
<span class="source-line-no">7654</span><span id="line-7654"></span>
<span class="source-line-no">7655</span><span id="line-7655"> assertFalse("Region lock holder should not have been interrupted", holderInterrupted.get());</span>
<span class="source-line-no">7656</span><span id="line-7656"> }</span>
<span class="source-line-no">7657</span><span id="line-7657"></span>
<span class="source-line-no">7658</span><span id="line-7658"> @Test</span>
<span class="source-line-no">7659</span><span id="line-7659"> public void testCloseInterrupt() throws Exception {</span>
<span class="source-line-no">7660</span><span id="line-7660"> byte[] cf1 = Bytes.toBytes("CF1");</span>
<span class="source-line-no">7661</span><span id="line-7661"> byte[][] families = { cf1 };</span>
<span class="source-line-no">7662</span><span id="line-7662"> final int SLEEP_TIME = 10 * 1000;</span>
<span class="source-line-no">7663</span><span id="line-7663"></span>
<span class="source-line-no">7664</span><span id="line-7664"> Configuration conf = new Configuration(CONF);</span>
<span class="source-line-no">7665</span><span id="line-7665"> // Enable close thread interrupt and server abort behavior</span>
<span class="source-line-no">7666</span><span id="line-7666"> conf.setBoolean(HRegion.CLOSE_WAIT_ABORT, true);</span>
<span class="source-line-no">7667</span><span id="line-7667"> // Speed up the unit test, no need to wait default 10 seconds.</span>
<span class="source-line-no">7668</span><span id="line-7668"> conf.setInt(HRegion.CLOSE_WAIT_INTERVAL, 1000);</span>
<span class="source-line-no">7669</span><span id="line-7669"> region = initHRegion(tableName, method, conf, families);</span>
<span class="source-line-no">7670</span><span id="line-7670"></span>
<span class="source-line-no">7671</span><span id="line-7671"> final CountDownLatch latch = new CountDownLatch(1);</span>
<span class="source-line-no">7672</span><span id="line-7672"> final AtomicBoolean holderInterrupted = new AtomicBoolean();</span>
<span class="source-line-no">7673</span><span id="line-7673"> Thread holder = new Thread(new Runnable() {</span>
<span class="source-line-no">7674</span><span id="line-7674"> @Override</span>
<span class="source-line-no">7675</span><span id="line-7675"> public void run() {</span>
<span class="source-line-no">7676</span><span id="line-7676"> try {</span>
<span class="source-line-no">7677</span><span id="line-7677"> LOG.info("Starting region operation holder");</span>
<span class="source-line-no">7678</span><span id="line-7678"> region.startRegionOperation(Operation.SCAN);</span>
<span class="source-line-no">7679</span><span id="line-7679"> latch.countDown();</span>
<span class="source-line-no">7680</span><span id="line-7680"> try {</span>
<span class="source-line-no">7681</span><span id="line-7681"> Thread.sleep(SLEEP_TIME);</span>
<span class="source-line-no">7682</span><span id="line-7682"> } catch (InterruptedException e) {</span>
<span class="source-line-no">7683</span><span id="line-7683"> LOG.info("Interrupted");</span>
<span class="source-line-no">7684</span><span id="line-7684"> holderInterrupted.set(true);</span>
<span class="source-line-no">7685</span><span id="line-7685"> }</span>
<span class="source-line-no">7686</span><span id="line-7686"> } catch (Exception e) {</span>
<span class="source-line-no">7687</span><span id="line-7687"> throw new RuntimeException(e);</span>
<span class="source-line-no">7688</span><span id="line-7688"> } finally {</span>
<span class="source-line-no">7689</span><span id="line-7689"> try {</span>
<span class="source-line-no">7690</span><span id="line-7690"> region.closeRegionOperation();</span>
<span class="source-line-no">7691</span><span id="line-7691"> } catch (IOException e) {</span>
<span class="source-line-no">7692</span><span id="line-7692"> }</span>
<span class="source-line-no">7693</span><span id="line-7693"> LOG.info("Stopped region operation holder");</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"> });</span>
<span class="source-line-no">7697</span><span id="line-7697"></span>
<span class="source-line-no">7698</span><span id="line-7698"> holder.start();</span>
<span class="source-line-no">7699</span><span id="line-7699"> latch.await();</span>
<span class="source-line-no">7700</span><span id="line-7700"> region.close();</span>
<span class="source-line-no">7701</span><span id="line-7701"> region = null;</span>
<span class="source-line-no">7702</span><span id="line-7702"> holder.join();</span>
<span class="source-line-no">7703</span><span id="line-7703"></span>
<span class="source-line-no">7704</span><span id="line-7704"> assertTrue("Region lock holder was not interrupted", holderInterrupted.get());</span>
<span class="source-line-no">7705</span><span id="line-7705"> }</span>
<span class="source-line-no">7706</span><span id="line-7706"></span>
<span class="source-line-no">7707</span><span id="line-7707"> @Test</span>
<span class="source-line-no">7708</span><span id="line-7708"> public void testCloseAbort() throws Exception {</span>
<span class="source-line-no">7709</span><span id="line-7709"> byte[] cf1 = Bytes.toBytes("CF1");</span>
<span class="source-line-no">7710</span><span id="line-7710"> byte[][] families = { cf1 };</span>
<span class="source-line-no">7711</span><span id="line-7711"> final int SLEEP_TIME = 10 * 1000;</span>
<span class="source-line-no">7712</span><span id="line-7712"></span>
<span class="source-line-no">7713</span><span id="line-7713"> Configuration conf = new Configuration(CONF);</span>
<span class="source-line-no">7714</span><span id="line-7714"> // Enable close thread interrupt and server abort behavior.</span>
<span class="source-line-no">7715</span><span id="line-7715"> conf.setBoolean(HRegion.CLOSE_WAIT_ABORT, true);</span>
<span class="source-line-no">7716</span><span id="line-7716"> // Set the abort interval to a fraction of sleep time so we are guaranteed to be aborted.</span>
<span class="source-line-no">7717</span><span id="line-7717"> conf.setInt(HRegion.CLOSE_WAIT_TIME, SLEEP_TIME / 2);</span>
<span class="source-line-no">7718</span><span id="line-7718"> // Set the wait interval to a fraction of sleep time so we are guaranteed to be interrupted.</span>
<span class="source-line-no">7719</span><span id="line-7719"> conf.setInt(HRegion.CLOSE_WAIT_INTERVAL, SLEEP_TIME / 4);</span>
<span class="source-line-no">7720</span><span id="line-7720"> region = initHRegion(tableName, method, conf, families);</span>
<span class="source-line-no">7721</span><span id="line-7721"> RegionServerServices rsServices = mock(RegionServerServices.class);</span>
<span class="source-line-no">7722</span><span id="line-7722"> when(rsServices.getServerName()).thenReturn(ServerName.valueOf("localhost", 1000, 1000));</span>
<span class="source-line-no">7723</span><span id="line-7723"> region.rsServices = rsServices;</span>
<span class="source-line-no">7724</span><span id="line-7724"></span>
<span class="source-line-no">7725</span><span id="line-7725"> final CountDownLatch latch = new CountDownLatch(1);</span>
<span class="source-line-no">7726</span><span id="line-7726"> Thread holder = new Thread(new Runnable() {</span>
<span class="source-line-no">7727</span><span id="line-7727"> @Override</span>
<span class="source-line-no">7728</span><span id="line-7728"> public void run() {</span>
<span class="source-line-no">7729</span><span id="line-7729"> try {</span>
<span class="source-line-no">7730</span><span id="line-7730"> LOG.info("Starting region operation holder");</span>
<span class="source-line-no">7731</span><span id="line-7731"> region.startRegionOperation(Operation.SCAN);</span>
<span class="source-line-no">7732</span><span id="line-7732"> latch.countDown();</span>
<span class="source-line-no">7733</span><span id="line-7733"> // Hold the lock for SLEEP_TIME seconds no matter how many times we are interrupted.</span>
<span class="source-line-no">7734</span><span id="line-7734"> int timeRemaining = SLEEP_TIME;</span>
<span class="source-line-no">7735</span><span id="line-7735"> while (timeRemaining &gt; 0) {</span>
<span class="source-line-no">7736</span><span id="line-7736"> long start = EnvironmentEdgeManager.currentTime();</span>
<span class="source-line-no">7737</span><span id="line-7737"> try {</span>
<span class="source-line-no">7738</span><span id="line-7738"> Thread.sleep(timeRemaining);</span>
<span class="source-line-no">7739</span><span id="line-7739"> } catch (InterruptedException e) {</span>
<span class="source-line-no">7740</span><span id="line-7740"> LOG.info("Interrupted");</span>
<span class="source-line-no">7741</span><span id="line-7741"> }</span>
<span class="source-line-no">7742</span><span id="line-7742"> long end = EnvironmentEdgeManager.currentTime();</span>
<span class="source-line-no">7743</span><span id="line-7743"> timeRemaining -= end - start;</span>
<span class="source-line-no">7744</span><span id="line-7744"> if (timeRemaining &lt; 0) {</span>
<span class="source-line-no">7745</span><span id="line-7745"> timeRemaining = 0;</span>
<span class="source-line-no">7746</span><span id="line-7746"> }</span>
<span class="source-line-no">7747</span><span id="line-7747"> if (timeRemaining &gt; 0) {</span>
<span class="source-line-no">7748</span><span id="line-7748"> LOG.info("Sleeping again, remaining time " + timeRemaining + " ms");</span>
<span class="source-line-no">7749</span><span id="line-7749"> }</span>
<span class="source-line-no">7750</span><span id="line-7750"> }</span>
<span class="source-line-no">7751</span><span id="line-7751"> } catch (Exception e) {</span>
<span class="source-line-no">7752</span><span id="line-7752"> throw new RuntimeException(e);</span>
<span class="source-line-no">7753</span><span id="line-7753"> } finally {</span>
<span class="source-line-no">7754</span><span id="line-7754"> try {</span>
<span class="source-line-no">7755</span><span id="line-7755"> region.closeRegionOperation();</span>
<span class="source-line-no">7756</span><span id="line-7756"> } catch (IOException e) {</span>
<span class="source-line-no">7757</span><span id="line-7757"> }</span>
<span class="source-line-no">7758</span><span id="line-7758"> LOG.info("Stopped region operation holder");</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"> });</span>
<span class="source-line-no">7762</span><span id="line-7762"></span>
<span class="source-line-no">7763</span><span id="line-7763"> holder.start();</span>
<span class="source-line-no">7764</span><span id="line-7764"> latch.await();</span>
<span class="source-line-no">7765</span><span id="line-7765"> assertThrows(IOException.class, () -&gt; region.close());</span>
<span class="source-line-no">7766</span><span id="line-7766"> holder.join();</span>
<span class="source-line-no">7767</span><span id="line-7767"></span>
<span class="source-line-no">7768</span><span id="line-7768"> // Verify the region tried to abort the server</span>
<span class="source-line-no">7769</span><span id="line-7769"> verify(rsServices, atLeast(1)).abort(anyString(), any());</span>
<span class="source-line-no">7770</span><span id="line-7770"> }</span>
<span class="source-line-no">7771</span><span id="line-7771"></span>
<span class="source-line-no">7772</span><span id="line-7772"> @Test</span>
<span class="source-line-no">7773</span><span id="line-7773"> public void testInterruptProtection() throws Exception {</span>
<span class="source-line-no">7774</span><span id="line-7774"> byte[] cf1 = Bytes.toBytes("CF1");</span>
<span class="source-line-no">7775</span><span id="line-7775"> byte[][] families = { cf1 };</span>
<span class="source-line-no">7776</span><span id="line-7776"> final int SLEEP_TIME = 10 * 1000;</span>
<span class="source-line-no">7777</span><span id="line-7777"></span>
<span class="source-line-no">7778</span><span id="line-7778"> Configuration conf = new Configuration(CONF);</span>
<span class="source-line-no">7779</span><span id="line-7779"> // Enable close thread interrupt and server abort behavior.</span>
<span class="source-line-no">7780</span><span id="line-7780"> conf.setBoolean(HRegion.CLOSE_WAIT_ABORT, true);</span>
<span class="source-line-no">7781</span><span id="line-7781"> conf.setInt(HRegion.CLOSE_WAIT_INTERVAL, 1000);</span>
<span class="source-line-no">7782</span><span id="line-7782"> region = initHRegion(tableName, method, conf, families);</span>
<span class="source-line-no">7783</span><span id="line-7783"></span>
<span class="source-line-no">7784</span><span id="line-7784"> final CountDownLatch latch = new CountDownLatch(1);</span>
<span class="source-line-no">7785</span><span id="line-7785"> final AtomicBoolean holderInterrupted = new AtomicBoolean();</span>
<span class="source-line-no">7786</span><span id="line-7786"> Thread holder = new Thread(new Runnable() {</span>
<span class="source-line-no">7787</span><span id="line-7787"> @Override</span>
<span class="source-line-no">7788</span><span id="line-7788"> public void run() {</span>
<span class="source-line-no">7789</span><span id="line-7789"> try {</span>
<span class="source-line-no">7790</span><span id="line-7790"> LOG.info("Starting region operation holder");</span>
<span class="source-line-no">7791</span><span id="line-7791"> region.startRegionOperation(Operation.SCAN);</span>
<span class="source-line-no">7792</span><span id="line-7792"> LOG.info("Protecting against interrupts");</span>
<span class="source-line-no">7793</span><span id="line-7793"> region.disableInterrupts();</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"> latch.countDown();</span>
<span class="source-line-no">7796</span><span id="line-7796"> try {</span>
<span class="source-line-no">7797</span><span id="line-7797"> Thread.sleep(SLEEP_TIME);</span>
<span class="source-line-no">7798</span><span id="line-7798"> } catch (InterruptedException e) {</span>
<span class="source-line-no">7799</span><span id="line-7799"> LOG.info("Interrupted");</span>
<span class="source-line-no">7800</span><span id="line-7800"> holderInterrupted.set(true);</span>
<span class="source-line-no">7801</span><span id="line-7801"> }</span>
<span class="source-line-no">7802</span><span id="line-7802"> } finally {</span>
<span class="source-line-no">7803</span><span id="line-7803"> region.enableInterrupts();</span>
<span class="source-line-no">7804</span><span id="line-7804"> }</span>
<span class="source-line-no">7805</span><span id="line-7805"> } catch (Exception e) {</span>
<span class="source-line-no">7806</span><span id="line-7806"> throw new RuntimeException(e);</span>
<span class="source-line-no">7807</span><span id="line-7807"> } finally {</span>
<span class="source-line-no">7808</span><span id="line-7808"> try {</span>
<span class="source-line-no">7809</span><span id="line-7809"> region.closeRegionOperation();</span>
<span class="source-line-no">7810</span><span id="line-7810"> } catch (IOException e) {</span>
<span class="source-line-no">7811</span><span id="line-7811"> }</span>
<span class="source-line-no">7812</span><span id="line-7812"> LOG.info("Stopped region operation holder");</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"> });</span>
<span class="source-line-no">7816</span><span id="line-7816"></span>
<span class="source-line-no">7817</span><span id="line-7817"> holder.start();</span>
<span class="source-line-no">7818</span><span id="line-7818"> latch.await();</span>
<span class="source-line-no">7819</span><span id="line-7819"> region.close();</span>
<span class="source-line-no">7820</span><span id="line-7820"> region = null;</span>
<span class="source-line-no">7821</span><span id="line-7821"> holder.join();</span>
<span class="source-line-no">7822</span><span id="line-7822"></span>
<span class="source-line-no">7823</span><span id="line-7823"> assertFalse("Region lock holder should not have been interrupted", holderInterrupted.get());</span>
<span class="source-line-no">7824</span><span id="line-7824"> }</span>
<span class="source-line-no">7825</span><span id="line-7825"></span>
<span class="source-line-no">7826</span><span id="line-7826"> @Test</span>
<span class="source-line-no">7827</span><span id="line-7827"> public void testRegionOnCoprocessorsChange() throws IOException {</span>
<span class="source-line-no">7828</span><span id="line-7828"> byte[] cf1 = Bytes.toBytes("CF1");</span>
<span class="source-line-no">7829</span><span id="line-7829"> byte[][] families = { cf1 };</span>
<span class="source-line-no">7830</span><span id="line-7830"></span>
<span class="source-line-no">7831</span><span id="line-7831"> Configuration conf = new Configuration(CONF);</span>
<span class="source-line-no">7832</span><span id="line-7832"> region = initHRegion(tableName, method, conf, families);</span>
<span class="source-line-no">7833</span><span id="line-7833"> assertNull(region.getCoprocessorHost());</span>
<span class="source-line-no">7834</span><span id="line-7834"></span>
<span class="source-line-no">7835</span><span id="line-7835"> // set and verify the system coprocessors for region and user region</span>
<span class="source-line-no">7836</span><span id="line-7836"> Configuration newConf = new Configuration(conf);</span>
<span class="source-line-no">7837</span><span id="line-7837"> newConf.set(CoprocessorHost.REGION_COPROCESSOR_CONF_KEY, MetaTableMetrics.class.getName());</span>
<span class="source-line-no">7838</span><span id="line-7838"> newConf.set(CoprocessorHost.USER_REGION_COPROCESSOR_CONF_KEY,</span>
<span class="source-line-no">7839</span><span id="line-7839"> NoOpRegionCoprocessor.class.getName());</span>
<span class="source-line-no">7840</span><span id="line-7840"> // trigger configuration change</span>
<span class="source-line-no">7841</span><span id="line-7841"> region.onConfigurationChange(newConf);</span>
<span class="source-line-no">7842</span><span id="line-7842"> assertTrue(region.getCoprocessorHost() != null);</span>
<span class="source-line-no">7843</span><span id="line-7843"> Set&lt;String&gt; coprocessors = region.getCoprocessorHost().getCoprocessors();</span>
<span class="source-line-no">7844</span><span id="line-7844"> assertTrue(coprocessors.size() == 2);</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(MetaTableMetrics.class.getSimpleName()));</span>
<span class="source-line-no">7847</span><span id="line-7847"> assertTrue(region.getCoprocessorHost().getCoprocessors()</span>
<span class="source-line-no">7848</span><span id="line-7848"> .contains(NoOpRegionCoprocessor.class.getSimpleName()));</span>
<span class="source-line-no">7849</span><span id="line-7849"></span>
<span class="source-line-no">7850</span><span id="line-7850"> // remove region coprocessor and keep only user region coprocessor</span>
<span class="source-line-no">7851</span><span id="line-7851"> newConf.unset(CoprocessorHost.REGION_COPROCESSOR_CONF_KEY);</span>
<span class="source-line-no">7852</span><span id="line-7852"> region.onConfigurationChange(newConf);</span>
<span class="source-line-no">7853</span><span id="line-7853"> assertTrue(region.getCoprocessorHost() != null);</span>
<span class="source-line-no">7854</span><span id="line-7854"> coprocessors = region.getCoprocessorHost().getCoprocessors();</span>
<span class="source-line-no">7855</span><span id="line-7855"> assertTrue(coprocessors.size() == 1);</span>
<span class="source-line-no">7856</span><span id="line-7856"> assertTrue(region.getCoprocessorHost().getCoprocessors()</span>
<span class="source-line-no">7857</span><span id="line-7857"> .contains(NoOpRegionCoprocessor.class.getSimpleName()));</span>
<span class="source-line-no">7858</span><span id="line-7858"> }</span>
<span class="source-line-no">7859</span><span id="line-7859"></span>
<span class="source-line-no">7860</span><span id="line-7860"> @Test</span>
<span class="source-line-no">7861</span><span id="line-7861"> public void testRegionOnCoprocessorsWithoutChange() throws IOException {</span>
<span class="source-line-no">7862</span><span id="line-7862"> byte[] cf1 = Bytes.toBytes("CF1");</span>
<span class="source-line-no">7863</span><span id="line-7863"> byte[][] families = { cf1 };</span>
<span class="source-line-no">7864</span><span id="line-7864"></span>
<span class="source-line-no">7865</span><span id="line-7865"> Configuration conf = new Configuration(CONF);</span>
<span class="source-line-no">7866</span><span id="line-7866"> conf.set(CoprocessorHost.REGION_COPROCESSOR_CONF_KEY,</span>
<span class="source-line-no">7867</span><span id="line-7867"> MetaTableMetrics.class.getCanonicalName());</span>
<span class="source-line-no">7868</span><span id="line-7868"> region = initHRegion(tableName, method, conf, families);</span>
<span class="source-line-no">7869</span><span id="line-7869"> // region service is null in unit test, we need to load the coprocessor once</span>
<span class="source-line-no">7870</span><span id="line-7870"> region.setCoprocessorHost(new RegionCoprocessorHost(region, null, conf));</span>
<span class="source-line-no">7871</span><span id="line-7871"> RegionCoprocessor regionCoprocessor =</span>
<span class="source-line-no">7872</span><span id="line-7872"> region.getCoprocessorHost().findCoprocessor(MetaTableMetrics.class.getName());</span>
<span class="source-line-no">7873</span><span id="line-7873"></span>
<span class="source-line-no">7874</span><span id="line-7874"> // simulate when other configuration may have changed and onConfigurationChange execute once</span>
<span class="source-line-no">7875</span><span id="line-7875"> region.onConfigurationChange(conf);</span>
<span class="source-line-no">7876</span><span id="line-7876"> RegionCoprocessor regionCoprocessorAfterOnConfigurationChange =</span>
<span class="source-line-no">7877</span><span id="line-7877"> region.getCoprocessorHost().findCoprocessor(MetaTableMetrics.class.getName());</span>
<span class="source-line-no">7878</span><span id="line-7878"> assertEquals(regionCoprocessor, regionCoprocessorAfterOnConfigurationChange);</span>
<span class="source-line-no">7879</span><span id="line-7879"> }</span>
<span class="source-line-no">7880</span><span id="line-7880"></span>
<span class="source-line-no">7881</span><span id="line-7881"> public static class NoOpRegionCoprocessor implements RegionCoprocessor, RegionObserver {</span>
<span class="source-line-no">7882</span><span id="line-7882"> // a empty region coprocessor class</span>
<span class="source-line-no">7883</span><span id="line-7883"> }</span>
<span class="source-line-no">7884</span><span id="line-7884">}</span>
</pre>
</div>
</main>
</body>
</html>