accumulo-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ktur...@apache.org
Subject [accumulo-website] branch asf-site updated: Jekyll build from master:52f812c
Date Fri, 08 Dec 2017 22:48:39 GMT
This is an automated email from the ASF dual-hosted git repository.

kturner pushed a commit to branch asf-site
in repository https://gitbox.apache.org/repos/asf/accumulo-website.git


The following commit(s) were added to refs/heads/asf-site by this push:
     new 5ce4558  Jekyll build from master:52f812c
5ce4558 is described below

commit 5ce4558c6d61acd9ac7c3fc7d8524b1fc9973a22
Author: Keith Turner <kturner@apache.org>
AuthorDate: Fri Dec 8 17:47:09 2017 -0500

    Jekyll build from master:52f812c
    
    Added conditional writer to tour
---
 feed.xml                                           |   4 +-
 tour/authorizations-code/index.html                |   4 +-
 tour/authorizations/index.html                     |   4 +-
 tour/basic-read-write/index.html                   |   4 +-
 tour/batch-scanner-code/index.html                 |   8 +-
 tour/batch-scanner/index.html                      |   4 +-
 .../index.html                                     |  73 +++++------
 tour/conditional-writer/index.html                 | 136 ++++++++++++++++++++-
 tour/data-model-code/index.html                    |   4 +-
 tour/data-model/index.html                         |   4 +-
 tour/getting-started/index.html                    |   4 +-
 tour/index.html                                    |   6 +
 tour/ranges-splits/index.html                      |   4 +-
 tour/using-iterators/index.html                    |   4 +-
 14 files changed, 198 insertions(+), 65 deletions(-)

diff --git a/feed.xml b/feed.xml
index fb6e542..e95efd2 100644
--- a/feed.xml
+++ b/feed.xml
@@ -6,8 +6,8 @@
 </description>
     <link>https://accumulo.apache.org/</link>
     <atom:link href="https://accumulo.apache.org/feed.xml" rel="self" type="application/rss+xml"/>
-    <pubDate>Fri, 08 Dec 2017 17:02:42 -0500</pubDate>
-    <lastBuildDate>Fri, 08 Dec 2017 17:02:42 -0500</lastBuildDate>
+    <pubDate>Fri, 08 Dec 2017 17:46:55 -0500</pubDate>
+    <lastBuildDate>Fri, 08 Dec 2017 17:46:55 -0500</lastBuildDate>
     <generator>Jekyll v3.5.2</generator>
     
     
diff --git a/tour/authorizations-code/index.html b/tour/authorizations-code/index.html
index b119a72..9e599dd 100644
--- a/tour/authorizations-code/index.html
+++ b/tour/authorizations-code/index.html
@@ -153,7 +153,7 @@
 
 <div id="tour-header">
   <h2><a href="/tour/">Accumulo Tour</a>: Authorizations Code</h2>
-  <p class="text-muted">Tour page 6 of 9</p>
+  <p class="text-muted">Tour page 6 of 11</p>
 </div>
 <div id="tour-content">
   <p>Below is a solution for the exercise.</p>
@@ -241,7 +241,7 @@ if (e.keyCode == '39') { window.location = '/tour/ranges-splits/'; }
     <a href="/tour/authorizations/">&lt;</a>
     
 
-    6 / 9
+    6 / 11
     
     <a href="/tour/ranges-splits/">&gt;</a>
     
diff --git a/tour/authorizations/index.html b/tour/authorizations/index.html
index 82b6734..f8f3fac 100644
--- a/tour/authorizations/index.html
+++ b/tour/authorizations/index.html
@@ -153,7 +153,7 @@
 
 <div id="tour-header">
   <h2><a href="/tour/">Accumulo Tour</a>: Authorizations</h2>
-  <p class="text-muted">Tour page 5 of 9</p>
+  <p class="text-muted">Tour page 5 of 11</p>
 </div>
 <div id="tour-content">
   <p><a href="https://static.javadoc.io/org.apache.accumulo/accumulo-core/1.8.1/org/apache/accumulo/core/security/Authorizations.html">Authorizations</a>
are a set of Strings that enable a user to read protected data. Users are granted authorizations
@@ -229,7 +229,7 @@ if (e.keyCode == '39') { window.location = '/tour/authorizations-code/';
}
     <a href="/tour/data-model-code/">&lt;</a>
     
 
-    5 / 9
+    5 / 11
     
     <a href="/tour/authorizations-code/">&gt;</a>
     
diff --git a/tour/basic-read-write/index.html b/tour/basic-read-write/index.html
index ad18351..5c29410 100644
--- a/tour/basic-read-write/index.html
+++ b/tour/basic-read-write/index.html
@@ -153,7 +153,7 @@
 
 <div id="tour-header">
   <h2><a href="/tour/">Accumulo Tour</a>: Writing and Reading</h2>
-  <p class="text-muted">Tour page 2 of 9</p>
+  <p class="text-muted">Tour page 2 of 11</p>
 </div>
 <div id="tour-content">
   <p>Accumulo is a big key/value store.  Writing data to Accumulo is flexible and fast.
 Like any database, Accumulo stores
@@ -227,7 +227,7 @@ if (e.keyCode == '39') { window.location = '/tour/data-model/'; }
     <a href="/tour/getting-started/">&lt;</a>
     
 
-    2 / 9
+    2 / 11
     
     <a href="/tour/data-model/">&gt;</a>
     
diff --git a/tour/batch-scanner-code/index.html b/tour/batch-scanner-code/index.html
index 11b0680..6e8559d 100644
--- a/tour/batch-scanner-code/index.html
+++ b/tour/batch-scanner-code/index.html
@@ -153,7 +153,7 @@
 
 <div id="tour-header">
   <h2><a href="/tour/">Accumulo Tour</a>: Batch Scanner Code</h2>
-  <p class="text-muted">Tour page 9 of 9</p>
+  <p class="text-muted">Tour page 9 of 11</p>
 </div>
 <div id="tour-content">
   <p>Below is a solution to the exercise.</p>
@@ -213,6 +213,8 @@ if (e.keyCode == '37') { window.location = '/tour/batch-scanner/'; }
 
 
 
+if (e.keyCode == '39') { window.location = '/tour/conditional-writer/'; }
+
 };
 </script>
 
@@ -222,7 +224,9 @@ if (e.keyCode == '37') { window.location = '/tour/batch-scanner/'; }
     <a href="/tour/batch-scanner/">&lt;</a>
     
 
-    9 / 9
+    9 / 11
+    
+    <a href="/tour/conditional-writer/">&gt;</a>
     
   </h2>
 </div>
diff --git a/tour/batch-scanner/index.html b/tour/batch-scanner/index.html
index d52fb8d..adb857f 100644
--- a/tour/batch-scanner/index.html
+++ b/tour/batch-scanner/index.html
@@ -153,7 +153,7 @@
 
 <div id="tour-header">
   <h2><a href="/tour/">Accumulo Tour</a>: Batch Scanner</h2>
-  <p class="text-muted">Tour page 8 of 9</p>
+  <p class="text-muted">Tour page 8 of 11</p>
 </div>
 <div id="tour-content">
   <p>Running on a single thread, a Scanner will retrieve a single Range of data and
return Keys in sorted order. A <a href="https://static.javadoc.io/org.apache.accumulo/accumulo-core/1.8.1/org/apache/accumulo/core/client/BatchScanner.html">BatchScanner</a>

@@ -219,7 +219,7 @@ if (e.keyCode == '39') { window.location = '/tour/batch-scanner-code/';
}
     <a href="/tour/ranges-splits/">&lt;</a>
     
 
-    8 / 9
+    8 / 11
     
     <a href="/tour/batch-scanner-code/">&gt;</a>
     
diff --git a/tour/ranges-splits/index.html b/tour/conditional-writer-code/index.html
similarity index 63%
copy from tour/ranges-splits/index.html
copy to tour/conditional-writer-code/index.html
index a0f74d4..a1693e7 100644
--- a/tour/ranges-splits/index.html
+++ b/tour/conditional-writer-code/index.html
@@ -25,7 +25,7 @@
 <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/v/bs/jq-2.2.3/dt-1.10.12/datatables.min.css">
 <link href="/css/accumulo.css" rel="stylesheet" type="text/css">
 
-<title>Ranges and Splits</title>
+<title>Conditional Writer Code</title>
 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
 <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa"
crossorigin="anonymous"></script>
@@ -146,75 +146,68 @@
         </div>
         <div id="content">
           
-          <h1 class="title">Ranges and Splits</h1>
+          <h1 class="title">Conditional Writer Code</h1>
           
           
 
 
 <div id="tour-header">
-  <h2><a href="/tour/">Accumulo Tour</a>: Ranges and Splits</h2>
-  <p class="text-muted">Tour page 7 of 9</p>
+  <h2><a href="/tour/">Accumulo Tour</a>: Conditional Writer Code</h2>
+  <p class="text-muted">Tour page 11 of 11</p>
 </div>
 <div id="tour-content">
-  <p>A <a href="https://static.javadoc.io/org.apache.accumulo/accumulo-core/1.8.1/org/apache/accumulo/core/data/Range.html">Range</a>
is a specified group of Keys. There are many different ways to create a Range.  Here are a
few examples:</p>
+  <p>Below is a solution to the excercise.</p>
+
+<div class="language-java highlighter-rouge"><pre class="highlight"><code>
 <span class="kd">static</span> <span class="kt">boolean</span> <span
class="nf">setAddress</span><span class="o">(</span><span class="n">Connector</span>
<span class="n">conn</span><span class="o">,</span> <span class="n">String</span>
<span class="n">id</span><span class="o">,</span> <span class="n">String</span>
<span class="n">expectedAddr</span><span class="o">,</span> <span
class="n">String</span> <span clas [...]
+    <span class="k">try</span> <span class="o">(</span><span class="n">ConditionalWriter</span>
<span class="n">writer</span> <span class="o">=</span> <span class="n">conn</span><span
class="o">.</span><span class="na">createConditionalWriter</span><span
class="o">(</span><span class="s">"GothamPD"</span><span class="o">,</span>
<span class="k">new</span> <span class="n">ConditionalWriterConfig</span><span
class="o">()))</span> <span class="o">{</span>
+      <span class="n">Condition</span> <span class="n">condition</span>
<span class="o">=</span> <span class="k">new</span> <span class="n">Condition</span><span
class="o">(</span><span class="s">"location"</span><span class="o">,</span>
<span class="s">"home"</span><span class="o">);</span>
+      <span class="k">if</span><span class="o">(</span><span class="n">expectedAddr</span>
<span class="o">!=</span> <span class="kc">null</span><span class="o">)</span>
<span class="o">{</span>
+        <span class="n">condition</span><span class="o">.</span><span
class="na">setValue</span><span class="o">(</span><span class="n">expectedAddr</span><span
class="o">);</span>
+      <span class="o">}</span>
+      <span class="n">ConditionalMutation</span> <span class="n">mutation</span>
<span class="o">=</span> <span class="k">new</span> <span class="n">ConditionalMutation</span><span
class="o">(</span><span class="n">id</span><span class="o">,</span>
<span class="n">condition</span><span class="o">);</span>
+      <span class="n">mutation</span><span class="o">.</span><span
class="na">put</span><span class="o">(</span><span class="s">"location"</span><span
class="o">,</span> <span class="s">"home"</span><span class="o">,</span>
<span class="n">newAddr</span><span class="o">);</span>
+      <span class="k">return</span> <span class="n">writer</span><span
class="o">.</span><span class="na">write</span><span class="o">(</span><span
class="n">mutation</span><span class="o">).</span><span class="na">getStatus</span><span
class="o">()</span> <span class="o">==</span> <span class="n">Status</span><span
class="o">.</span><span class="na">ACCEPTED</span><span class="o">;</span>
+    <span class="o">}</span> <span class="k">catch</span> <span
class="o">(</span><span class="n">Exception</span> <span class="n">e</span><span
class="o">)</span> <span class="o">{</span>
+      <span class="k">throw</span> <span class="k">new</span> <span
class="nf">RuntimeException</span><span class="o">(</span><span class="n">e</span><span
class="o">);</span>
+    <span class="o">}</span>
+  <span class="o">}</span>
 
-<div class="language-java highlighter-rouge"><pre class="highlight"><code><span
class="n">Range</span> <span class="n">r1</span> <span class="o">=</span>
<span class="k">new</span> <span class="n">Range</span><span class="o">(</span><span
class="n">startKey</span><span class="o">,</span> <span class="n">endKey</span><span
class="o">);</span>  <span class="c1">// Creates a range from startKey inclusive
to endKey inclusive.</span>
-<span class="n">Range</span> <span class="n">r2</span> <span class="o">=</span>
<span class="k">new</span> <span class="n">Range</span><span class="o">(</span><span
class="n">row</span><span class="o">);</span>               <span
class="c1">// Creates a range that covers an entire row.</span>
-<span class="n">Range</span> <span class="n">r3</span> <span class="o">=</span>
<span class="k">new</span> <span class="n">Range</span><span class="o">(</span><span
class="n">startRow</span><span class="o">,</span> <span class="n">endRow</span><span
class="o">);</span>  <span class="c1">// Creates a range from startRow inclusive
to endRow inclusive.</span>
 </code></pre>
 </div>
 
-<p>A Scanner by default will scan all Keys in a table but this can be inefficient.
It is a good practice to set a range on a Scanner.</p>
-
-<div class="language-java highlighter-rouge"><pre class="highlight"><code><span
class="n">scanner</span><span class="o">.</span><span class="na">setRange</span><span
class="o">(</span><span class="k">new</span> <span class="n">Range</span><span
class="o">(</span><span class="s">"id0000"</span><span class="o">,</span>
<span class="s">"id0010"</span><span class="o">));</span>  <span
class="c1">// returns rows from id0000 to id0010</span>
+<p>The following output shows running the example with a conditional writer.
+Threads retry when conditional mutations are rejected.  The final address has
+all three modifications.</p>
+
+<div class="highlighter-rouge"><pre class="highlight"><code>Thread  37
attempting change '  1007 Mountain Drive, Gotham, New York  ' -&gt; '  1007 Mountain Dr,
Gotham, New York  '
+Thread  38 attempting change '  1007 Mountain Drive, Gotham, New York  ' -&gt; '1007
Mountain Drive, Gotham, New York'
+Thread  39 attempting change '  1007 Mountain Drive, Gotham, New York  ' -&gt; '  1007
Mountain Drive, Gotham, NY  '
+Thread  38 attempting change '  1007 Mountain Dr, Gotham, New York  ' -&gt; '1007 Mountain
Dr, Gotham, New York'
+Thread  39 attempting change '  1007 Mountain Dr, Gotham, New York  ' -&gt; '  1007 Mountain
Dr, Gotham, NY  '
+Thread  39 attempting change '1007 Mountain Dr, Gotham, New York' -&gt; '1007 Mountain
Dr, Gotham, NY'
+Final address : '1007 Mountain Dr, Gotham, NY'
 </code></pre>
 </div>
 
-<p>As your data grows larger, Accumulo will split tables into smaller pieces called
Tablets.  Tablets can then be distributed across multiple Tablet Servers.<br />
-By default, a table will get split into Tablets on row boundaries, guaranteeing an entire
row to be on one Tablet Server.  We have the ability to 
-tell Accumulo where to split tables by setting split points. This is done using <code
class="highlighter-rouge">addSplits</code> in the <a href="https://static.javadoc.io/org.apache.accumulo/accumulo-core/1.8.1/org/apache/accumulo/core/client/admin/TableOperations.html">TableOperations</a>
API.  The image below 
-demonstrates how Accumulo splits data.</p>
-
-<p><img src="https://accumulo.apache.org/images/docs/data_distribution.png" alt="data
distribution" /></p>
-
-<p>Take a minute to learn these Accumulo terms:</p>
-<ul>
-  <li><strong>Tablet</strong> - A partition of a table.</li>
-  <li><strong>Split</strong> - A point where tables are partitioned into
separate tablets.</li>
-  <li><strong>Flush</strong> - Action taken when data is written from memory
to disk.</li>
-  <li><strong>Compact</strong> - Action taken when files on disk are consolidated.</li>
-  <li><strong>Iterator</strong> - A server side mechanism that can filter
and modify Key/Value pairs.</li>
-</ul>
-
-<p>Knowing these terms are critical when working closely with Accumulo.  Iterators
are especially unique and powerful.  More on them later.</p>
-
-<p>When working with large amounts of data across many Tablet Servers, a simple Scanner
might not do the trick. Next lesson we learn about the power of 
-the multi-threaded BatchScanner!</p>
-
-
 </div>
 
 <script>
 document.body.onkeyup = function(e){
 
-if (e.keyCode == '37') { window.location = '/tour/authorizations-code/'; }
+if (e.keyCode == '37') { window.location = '/tour/conditional-writer/'; }
 
 
 
-if (e.keyCode == '39') { window.location = '/tour/batch-scanner/'; }
-
 };
 </script>
 
 <div class="text-center">
   <h2>
     
-    <a href="/tour/authorizations-code/">&lt;</a>
+    <a href="/tour/conditional-writer/">&lt;</a>
     
 
-    7 / 9
-    
-    <a href="/tour/batch-scanner/">&gt;</a>
+    11 / 11
     
   </h2>
 </div>
diff --git a/tour/conditional-writer/index.html b/tour/conditional-writer/index.html
index 7b53dcb..a464a35 100644
--- a/tour/conditional-writer/index.html
+++ b/tour/conditional-writer/index.html
@@ -153,26 +153,156 @@
 
 <div id="tour-header">
   <h2><a href="/tour/">Accumulo Tour</a>: Conditional Writer</h2>
-  <p class="text-muted">Tour page  of 9</p>
+  <p class="text-muted">Tour page 10 of 11</p>
 </div>
 <div id="tour-content">
-  
+  <p>Suppose the Gotham PD is storing home addresses for persons of interest in
+Accumulo.  We want to correctly handle the case of multiple users editing the
+same address at the same time. The following sequence of events shows an example
+of how this can go wrong.</p>
+
+<ol>
+  <li>User 0 sets the key <code class="highlighter-rouge">id0001:location:home</code>
to <code class="highlighter-rouge">1007 Mountain Drive, Gotham, New York</code></li>
+  <li>User 1 reads <code class="highlighter-rouge">id0001:location:home</code></li>
+  <li>User 2 reads <code class="highlighter-rouge">id0001:location:home</code></li>
+  <li>User 1 replaces <code class="highlighter-rouge">Drive</code> with
<code class="highlighter-rouge">Dr</code></li>
+  <li>User 2 replaces <code class="highlighter-rouge">New York</code> with
<code class="highlighter-rouge">NY</code></li>
+  <li>User 1 sets key <code class="highlighter-rouge">id0001:location:home</code>
to <code class="highlighter-rouge">1007 Mountain Dr, Gotham, New York</code></li>
+  <li>User 2 sets key <code class="highlighter-rouge">id0001:location:home</code>
to <code class="highlighter-rouge">1007 Mountain Drive, Gotham, NY</code></li>
+</ol>
+
+<p>In this situation the changes made by User 1 are lost, ending up with <code class="highlighter-rouge">1007
+Mountain Drive, Gotham, NY</code> instead of <code class="highlighter-rouge">1007
Mountain Dr, Gotham, NY</code>.  To
+correctly handle this, Accumulo offers the <a href="https://static.javadoc.io/org.apache.accumulo/accumulo-core/1.8.1/org/apache/accumulo/core/client/ConditionalWriter.html">ConditionalWriter</a>.
 The
+ConditionalWriter atomically checks conditions on a row and only applies a
+mutation when all conditions are satisfied.</p>
+
+<h2 id="exercise">Exercise</h2>
+
+<p>The following code simulates the concurrency in the situation above.  The code
+starts multiple threads, with each thread doing the following.</p>
+
+<ol>
+  <li>Read key’s value into memory using a scanner</li>
+  <li>Modify the copy in memory.</li>
+  <li>Write out the modified value from memory using a batch writer.</li>
+  <li>If write was unsuccessful, then goto step 1.</li>
+</ol>
+
+<p>This process can result in threads overwriting each other changes.  The problem
+is the batch writer always makes the update, even when the value has
+changed since it was read.</p>
+
+<div class="language-java highlighter-rouge"><pre class="highlight"><code>
 <span class="kd">static</span> <span class="n">String</span> <span
class="nf">getAddress</span><span class="o">(</span><span class="n">Connector</span>
<span class="n">conn</span><span class="o">,</span> <span class="n">String</span>
<span class="n">id</span><span class="o">)</span> <span class="o">{</span>
+    <span class="c1">// The IsolatedScanner ensures partial changes to a row are not
seen</span>
+    <span class="k">try</span> <span class="o">(</span><span class="n">Scanner</span>
<span class="n">scanner</span> <span class="o">=</span> <span class="k">new</span>
<span class="n">IsolatedScanner</span><span class="o">(</span><span
class="n">conn</span><span class="o">.</span><span class="na">createScanner</span><span
class="o">(</span><span class="s">"GothamPD"</span><span class="o">,</span>
<span class="n">Authorizations</span><span class="o">.</span><span
class="na">EMPTY</span>< [...]
+      <span class="n">scanner</span><span class="o">.</span><span
class="na">setRange</span><span class="o">(</span><span class="n">Range</span><span
class="o">.</span><span class="na">exact</span><span class="o">(</span><span
class="n">id</span><span class="o">,</span> <span class="s">"location"</span><span
class="o">,</span> <span class="s">"home"</span><span class="o">));</span>
+      <span class="k">for</span> <span class="o">(</span><span
class="n">Entry</span><span class="o">&lt;</span><span class="n">Key</span><span
class="o">,</span><span class="n">Value</span><span class="o">&gt;</span>
<span class="n">entry</span> <span class="o">:</span> <span class="n">scanner</span><span
class="o">)</span> <span class="o">{</span>
+        <span class="k">return</span> <span class="n">entry</span><span
class="o">.</span><span class="na">getValue</span><span class="o">().</span><span
class="na">toString</span><span class="o">();</span>
+      <span class="o">}</span>
+      <span class="k">return</span> <span class="kc">null</span><span
class="o">;</span>
+    <span class="o">}</span> <span class="k">catch</span> <span
class="o">(</span><span class="n">TableNotFoundException</span> <span
class="n">e</span><span class="o">)</span> <span class="o">{</span>
+      <span class="k">throw</span> <span class="k">new</span> <span
class="nf">RuntimeException</span><span class="o">(</span><span class="n">e</span><span
class="o">);</span>
+    <span class="o">}</span>
+  <span class="o">}</span>
+
+  <span class="kd">static</span> <span class="kt">boolean</span>
<span class="nf">setAddress</span><span class="o">(</span><span
class="n">Connector</span> <span class="n">conn</span><span class="o">,</span>
<span class="n">String</span> <span class="n">id</span><span class="o">,</span>
<span class="n">String</span> <span class="n">expectedAddr</span><span
class="o">,</span> <span class="n">String</span> <span class="n">newAddr</span><span
class="o">)</span> <span class="o">{</span>
+    <span class="k">try</span> <span class="o">(</span><span class="n">BatchWriter</span>
<span class="n">writer</span> <span class="o">=</span> <span class="n">conn</span><span
class="o">.</span><span class="na">createBatchWriter</span><span class="o">(</span><span
class="s">"GothamPD"</span><span class="o">,</span> <span class="k">new</span>
<span class="n">BatchWriterConfig</span><span class="o">()))</span>
<span class="o">{</span>
+      <span class="n">Mutation</span> <span class="n">mutation</span>
<span class="o">=</span> <span class="k">new</span> <span class="n">Mutation</span><span
class="o">(</span><span class="n">id</span><span class="o">);</span>
+      <span class="n">mutation</span><span class="o">.</span><span
class="na">put</span><span class="o">(</span><span class="s">"location"</span><span
class="o">,</span> <span class="s">"home"</span><span class="o">,</span>
<span class="n">newAddr</span><span class="o">);</span>
+      <span class="n">writer</span><span class="o">.</span><span
class="na">addMutation</span><span class="o">(</span><span class="n">mutation</span><span
class="o">);</span>
+      <span class="k">return</span> <span class="kc">true</span><span
class="o">;</span>
+    <span class="o">}</span> <span class="k">catch</span> <span
class="o">(</span><span class="n">Exception</span> <span class="n">e</span><span
class="o">)</span> <span class="o">{</span>
+      <span class="k">throw</span> <span class="k">new</span> <span
class="nf">RuntimeException</span><span class="o">(</span><span class="n">e</span><span
class="o">);</span>
+    <span class="o">}</span>
+  <span class="o">}</span>
+
+  <span class="kd">public</span> <span class="kd">static</span> <span
class="n">Future</span><span class="o">&lt;</span><span class="n">Void</span><span
class="o">&gt;</span> <span class="nf">modifyAddress</span><span
class="o">(</span><span class="n">Connector</span> <span class="n">conn</span><span
class="o">,</span> <span class="n">String</span> <span class="n">id</span><span
class="o">,</span> <span class="n">Function</span><span class="o">&lt;</span><span
class="n">String</span><spa [...]
+    <span class="k">return</span> <span class="n">CompletableFuture</span><span
class="o">.</span><span class="na">runAsync</span><span class="o">(()</span>
<span class="o">-&gt;</span> <span class="o">{</span>
+      <span class="n">String</span> <span class="n">currAddr</span><span
class="o">,</span> <span class="n">newAddr</span><span class="o">;</span>
+      <span class="k">do</span> <span class="o">{</span>
+        <span class="n">currAddr</span> <span class="o">=</span>
<span class="n">getAddress</span><span class="o">(</span><span
class="n">conn</span><span class="o">,</span> <span class="n">id</span><span
class="o">);</span>
+        <span class="n">newAddr</span> <span class="o">=</span> <span
class="n">modifier</span><span class="o">.</span><span class="na">apply</span><span
class="o">(</span><span class="n">currAddr</span><span class="o">);</span>
+        <span class="n">System</span><span class="o">.</span><span
class="na">out</span><span class="o">.</span><span class="na">printf</span><span
class="o">(</span><span class="s">"Thread %3d attempting change %20s -&gt;
%-20s\n"</span><span class="o">,</span>
+            <span class="n">Thread</span><span class="o">.</span><span
class="na">currentThread</span><span class="o">().</span><span class="na">getId</span><span
class="o">(),</span> <span class="s">"'"</span><span class="o">+</span><span
class="n">currAddr</span><span class="o">+</span><span class="s">"'"</span><span
class="o">,</span> <span class="s">"'"</span><span class="o">+</span><span
class="n">newAddr</span><span class="o">+</span><span class="s">"'"</span><span
class="o">);</span>
+      <span class="o">}</span> <span class="k">while</span> <span
class="o">(!</span><span class="n">setAddress</span><span class="o">(</span><span
class="n">conn</span><span class="o">,</span> <span class="n">id</span><span
class="o">,</span> <span class="n">currAddr</span><span class="o">,</span>
<span class="n">newAddr</span><span class="o">));</span>
+    <span class="o">});</span>
+  <span class="o">}</span>
+
+  <span class="kd">static</span> <span class="kt">void</span> <span
class="nf">exercise</span><span class="o">(</span><span class="n">MiniAccumuloCluster</span>
<span class="n">mac</span><span class="o">)</span> <span class="kd">throws</span>
<span class="n">Exception</span> <span class="o">{</span>
+    <span class="n">Connector</span> <span class="n">conn</span>
<span class="o">=</span> <span class="n">mac</span><span class="o">.</span><span
class="na">getConnector</span><span class="o">(</span><span class="s">"root"</span><span
class="o">,</span> <span class="s">"tourguide"</span><span class="o">);</span>
+    <span class="n">conn</span><span class="o">.</span><span class="na">tableOperations</span><span
class="o">().</span><span class="na">create</span><span class="o">(</span><span
class="s">"GothamPD"</span><span class="o">);</span>
+
+    <span class="n">String</span> <span class="n">id</span> <span
class="o">=</span> <span class="s">"id0001"</span><span class="o">;</span>
+
+    <span class="n">setAddress</span><span class="o">(</span><span
class="n">conn</span><span class="o">,</span> <span class="n">id</span><span
class="o">,</span> <span class="kc">null</span><span class="o">,</span>
<span class="s">"  1007 Mountain Drive, Gotham, New York  "</span><span class="o">);</span>
+
+    <span class="c1">// create async operation to trim whitespace</span>
+    <span class="n">Future</span><span class="o">&lt;</span><span
class="n">Void</span><span class="o">&gt;</span> <span class="n">future1</span>
<span class="o">=</span> <span class="n">modifyAddress</span><span
class="o">(</span><span class="n">conn</span><span class="o">,</span>
<span class="n">id</span><span class="o">,</span> <span class="nl">String:</span><span
class="o">:</span><span class="n">trim</span><span class="o">);</span>
+
+    <span class="c1">// create async operation to replace Dr with Drive</span>
+    <span class="n">Future</span><span class="o">&lt;</span><span
class="n">Void</span><span class="o">&gt;</span> <span class="n">future2</span>
<span class="o">=</span> <span class="n">modifyAddress</span><span
class="o">(</span><span class="n">conn</span><span class="o">,</span>
<span class="n">id</span><span class="o">,</span> <span class="n">addr</span>
<span class="o">-&gt;</span> <span class="n">addr</span><span
class="o">.</span><span class="na">replace</span><span class="o">(</s
[...]
+
+    <span class="c1">// create async operation to replace New York with NY</span>
+    <span class="n">Future</span><span class="o">&lt;</span><span
class="n">Void</span><span class="o">&gt;</span> <span class="n">future3</span>
<span class="o">=</span> <span class="n">modifyAddress</span><span
class="o">(</span><span class="n">conn</span><span class="o">,</span>
<span class="n">id</span><span class="o">,</span> <span class="n">addr</span>
<span class="o">-&gt;</span> <span class="n">addr</span><span
class="o">.</span><span class="na">replace</span><span class="o">(</s
[...]
+
+    <span class="c1">// wait for async operations to complete</span>
+    <span class="n">future1</span><span class="o">.</span><span
class="na">get</span><span class="o">();</span>
+    <span class="n">future2</span><span class="o">.</span><span
class="na">get</span><span class="o">();</span>
+    <span class="n">future3</span><span class="o">.</span><span
class="na">get</span><span class="o">();</span>
+
+    <span class="c1">// print the address stored in Accumulo</span>
+    <span class="n">System</span><span class="o">.</span><span
class="na">out</span><span class="o">.</span><span class="na">println</span><span
class="o">(</span><span class="s">"Final address : '"</span><span
class="o">+</span><span class="n">getAddress</span><span class="o">(</span><span
class="n">conn</span><span class="o">,</span> <span class="n">id</span><span
class="o">)+</span><span class="s">"'"</span><span class="o">);</span>
+  <span class="o">}</span>
+</code></pre>
+</div>
+
+<p>The following is one of a few possible outputs.  Notice that only the
+modification of <code class="highlighter-rouge">Drive</code> to <code class="highlighter-rouge">Dr</code>
shows up in the final output.  The other
+modifications were lost.</p>
+
+<div class="highlighter-rouge"><pre class="highlight"><code>Thread  36
attempting change '  1007 Mountain Drive, Gotham, New York  ' -&gt; '1007 Mountain Drive,
Gotham, New York'
+Thread  38 attempting change '  1007 Mountain Drive, Gotham, New York  ' -&gt; '  1007
Mountain Drive, Gotham, NY  '
+Thread  37 attempting change '  1007 Mountain Drive, Gotham, New York  ' -&gt; '  1007
Mountain Dr, Gotham, New York  '
+Final address : '  1007 Mountain Dr, Gotham, New York  '
+</code></pre>
+</div>
+
+<p>To fix this example, make the following changes in <code class="highlighter-rouge">setAddress()</code>
to use a
+ConditionalWriter.</p>
+
+<ul>
+  <li>Call <a href="https://static.javadoc.io/org.apache.accumulo/accumulo-core/1.8.1/org/apache/accumulo/core/client/Connector.html#createConditionalWriter(java.lang.String,%20org.apache.accumulo.core.client.ConditionalWriterConfig)">createConditionalWriter</a>
instead of creating a batch writer</li>
+  <li>Create a <a href="https://static.javadoc.io/org.apache.accumulo/accumulo-core/1.8.1/org/apache/accumulo/core/data/Condition.html">Condition</a>
for the column ‘location:home’.  If <code class="highlighter-rouge">expectedAddr</code>
is not null, then call <a href="https://static.javadoc.io/org.apache.accumulo/accumulo-core/1.8.1/org/apache/accumulo/core/data/Condition.html#setValue(java.lang.CharSequence)">setValue</a>
passing <code class="highlighter-rouge">expectedAddr</code>.  If [...]
+  <li>Replace Mutation with a <a href="https://static.javadoc.io/org.apache.accumulo/accumulo-core/1.8.1/org/apache/accumulo/core/data/ConditionalMutation.html">ConditionalMutation</a>
and pass the condition to its constructor.</li>
+  <li>Call <a href="https://static.javadoc.io/org.apache.accumulo/accumulo-core/1.8.1/org/apache/accumulo/core/client/ConditionalWriter.html#write(org.apache.accumulo.core.data.ConditionalMutation)">write</a>
passing it the conditional mutation.</li>
+  <li>Return <code class="highlighter-rouge">true</code> if <a href="https://static.javadoc.io/org.apache.accumulo/accumulo-core/1.8.1/org/apache/accumulo/core/client/ConditionalWriter.Result.html#getStatus()">getStatus</a>
from the <a href="https://static.javadoc.io/org.apache.accumulo/accumulo-core/1.8.1/org/apache/accumulo/core/client/ConditionalWriter.Result.html">Result</a>
returned by <a href="https://static.javadoc.io/org.apache.accumulo/accumulo-core/1.8.1/org/apache/accumulo/cor
[...]
+</ul>
+
 
 </div>
 
 <script>
 document.body.onkeyup = function(e){
 
+if (e.keyCode == '37') { window.location = '/tour/batch-scanner-code/'; }
+
 
 
+if (e.keyCode == '39') { window.location = '/tour/conditional-writer-code/'; }
+
 };
 </script>
 
 <div class="text-center">
   <h2>
     
+    <a href="/tour/batch-scanner-code/">&lt;</a>
+    
 
-     / 9
+    10 / 11
+    
+    <a href="/tour/conditional-writer-code/">&gt;</a>
     
   </h2>
 </div>
diff --git a/tour/data-model-code/index.html b/tour/data-model-code/index.html
index 1fd5f6b..1527c6d 100644
--- a/tour/data-model-code/index.html
+++ b/tour/data-model-code/index.html
@@ -153,7 +153,7 @@
 
 <div id="tour-header">
   <h2><a href="/tour/">Accumulo Tour</a>: Data Model Code</h2>
-  <p class="text-muted">Tour page 4 of 9</p>
+  <p class="text-muted">Tour page 4 of 11</p>
 </div>
 <div id="tour-content">
   <p>Below is the solution for the exercise.</p>
@@ -234,7 +234,7 @@ if (e.keyCode == '39') { window.location = '/tour/authorizations/'; }
     <a href="/tour/data-model/">&lt;</a>
     
 
-    4 / 9
+    4 / 11
     
     <a href="/tour/authorizations/">&gt;</a>
     
diff --git a/tour/data-model/index.html b/tour/data-model/index.html
index 9c27982..4bcdf41 100644
--- a/tour/data-model/index.html
+++ b/tour/data-model/index.html
@@ -153,7 +153,7 @@
 
 <div id="tour-header">
   <h2><a href="/tour/">Accumulo Tour</a>: Data Model</h2>
-  <p class="text-muted">Tour page 3 of 9</p>
+  <p class="text-muted">Tour page 3 of 11</p>
 </div>
 <div id="tour-content">
   <p>Data is stored in Accumulo in a distributed sorted map. The Keys of the map are
broken up logically into a few different parts, 
@@ -202,7 +202,7 @@ if (e.keyCode == '39') { window.location = '/tour/data-model-code/'; }
     <a href="/tour/basic-read-write/">&lt;</a>
     
 
-    3 / 9
+    3 / 11
     
     <a href="/tour/data-model-code/">&gt;</a>
     
diff --git a/tour/getting-started/index.html b/tour/getting-started/index.html
index d61c5bd..732d789 100644
--- a/tour/getting-started/index.html
+++ b/tour/getting-started/index.html
@@ -153,7 +153,7 @@
 
 <div id="tour-header">
   <h2><a href="/tour/">Accumulo Tour</a>: Getting Started</h2>
-  <p class="text-muted">Tour page 1 of 9</p>
+  <p class="text-muted">Tour page 1 of 11</p>
 </div>
 <div id="tour-content">
   <p>First make sure you have Java, Maven and Git installed on your machine.  Oh you
are already rocking? OK let’s go!</p>
@@ -202,7 +202,7 @@ if (e.keyCode == '39') { window.location = '/tour/basic-read-write/';
}
   <h2>
     
 
-    1 / 9
+    1 / 11
     
     <a href="/tour/basic-read-write/">&gt;</a>
     
diff --git a/tour/index.html b/tour/index.html
index a1dda02..81c3190 100644
--- a/tour/index.html
+++ b/tour/index.html
@@ -191,6 +191,12 @@ or <a href="https://issues.apache.org/jira/projects/ACCUMULO">create
an issue</a
   <li>
     <p><a href="/tour/batch-scanner-code/">Batch Scanner Code</a></p>
   </li>
+  <li>
+    <p><a href="/tour/conditional-writer/">Conditional Writer</a></p>
+  </li>
+  <li>
+    <p><a href="/tour/conditional-writer-code/">Conditional Writer Code</a></p>
+  </li>
 </ol>
 
 
diff --git a/tour/ranges-splits/index.html b/tour/ranges-splits/index.html
index a0f74d4..e70b03c 100644
--- a/tour/ranges-splits/index.html
+++ b/tour/ranges-splits/index.html
@@ -153,7 +153,7 @@
 
 <div id="tour-header">
   <h2><a href="/tour/">Accumulo Tour</a>: Ranges and Splits</h2>
-  <p class="text-muted">Tour page 7 of 9</p>
+  <p class="text-muted">Tour page 7 of 11</p>
 </div>
 <div id="tour-content">
   <p>A <a href="https://static.javadoc.io/org.apache.accumulo/accumulo-core/1.8.1/org/apache/accumulo/core/data/Range.html">Range</a>
is a specified group of Keys. There are many different ways to create a Range.  Here are a
few examples:</p>
@@ -212,7 +212,7 @@ if (e.keyCode == '39') { window.location = '/tour/batch-scanner/'; }
     <a href="/tour/authorizations-code/">&lt;</a>
     
 
-    7 / 9
+    7 / 11
     
     <a href="/tour/batch-scanner/">&gt;</a>
     
diff --git a/tour/using-iterators/index.html b/tour/using-iterators/index.html
index f40cf94..4a970f1 100644
--- a/tour/using-iterators/index.html
+++ b/tour/using-iterators/index.html
@@ -153,7 +153,7 @@
 
 <div id="tour-header">
   <h2><a href="/tour/">Accumulo Tour</a>: Using Iterators</h2>
-  <p class="text-muted">Tour page  of 9</p>
+  <p class="text-muted">Tour page  of 11</p>
 </div>
 <div id="tour-content">
   
@@ -172,7 +172,7 @@ document.body.onkeyup = function(e){
   <h2>
     
 
-     / 9
+     / 11
     
   </h2>
 </div>

-- 
To stop receiving notification emails like this one, please contact
['"commits@accumulo.apache.org" <commits@accumulo.apache.org>'].

Mime
View raw message