http://git-wip-us.apache.org/repos/asf/incubator-fluo-website/blob/76022205/tour/multi-get/index.html ---------------------------------------------------------------------- diff --git a/tour/multi-get/index.html b/tour/multi-get/index.html new file mode 100644 index 0000000..3032974 --- /dev/null +++ b/tour/multi-get/index.html @@ -0,0 +1,272 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <meta http-equiv="X-UA-Compatible" content="IE=edge"> + <meta name="viewport" content="width=device-width, initial-scale=1"> + <link rel="stylesheet" href="/stylesheets/fluo.css"> + <link rel="stylesheet" type="text/css" href="https://fonts.googleapis.com/css?family=Montserrat:700,400"> + <link rel="stylesheet" type="text/css" href="https://fonts.googleapis.com/css?family=Merriweather"> + <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.2.0/css/font-awesome.min.css" > + <link rel="canonical" href="http://fluo.io/tour/multi-get/"> + <link rel="icon" type="image/png" href="/resources/favicon.png"> + <title>Fetching multiple cells | Apache Fluo</title> + <!--[if lt IE 9]> + <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script> + <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script> + <![endif]--> + </head> + <body> + <div id="fluo-nav" class="navbar navbar-default navbar-static-top"> + <div class="container"> + <div class="navbar-header"> + <div class="navbar-toggle-wrapper visible-xs"> + <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".js-navbar-collapse"> + <span class="icon-bar"></span> + <span class="icon-bar"></span> + <span class="icon-bar"></span> + </button> + </div> + <a href="/" class="navbar-brand"><img src="/resources/fluo-logo.png" alt="Apache Fluo"></a> + </div> + <div class="collapse navbar-collapse js-navbar-collapse" style="margin-top: 20px"> + <ul class="navbar-nav nav"> + <li><a href="/docs/">Documentation</a></li> + <li><a href="/download/">Download</a></li> + <li class="dropdown"> + <a class="dropdown-toggle" data-toggle="dropdown" href="#">Community<span class="caret"></span></a> + <ul class="dropdown-menu"> + <li><a href="/getinvolved/">Get Involved</a></li> + <li><a href="/blog/">Blog</a></li> + <li><a href="/people/">People</a></li> + <li><a href="/related-projects/">Related Projects</a></li> + <li><a href="/poweredby/">Powered By</a></li> + </ul> + </li> + <li class="dropdown"> + <a class="dropdown-toggle" data-toggle="dropdown" href="#">Contributing<span class="caret"></span></a> + <ul class="dropdown-menu"> + <li><a href="/how-to-contribute/">How To Contribute</a></li> + <li><a href="/release-process/">Release Process</a></li> + </ul> + </li> + </ul> + <ul class="navbar-nav nav navbar-right"> + <li class="dropdown"> + <a class="dropdown-toggle" data-toggle="dropdown" href="#">Apache Software Foundation<span class="caret"></span></a> + <ul class="dropdown-menu"> + <li><a href="https://www.apache.org">Apache Homepage</a></li> + <li><a href="https://www.apache.org/licenses/LICENSE-2.0">License</a></li> + <li><a href="https://www.apache.org/foundation/sponsorship">Sponsorship</i></a></li> + <li><a href="https://www.apache.org/security">Security</a></li> + <li><a href="https://www.apache.org/foundation/thanks">Thanks</a></li> + <li><a href="https://www.apache.org/foundation/policies/conduct">Code of Conduct</a></li> + </ul> + </li> + </ul> + </div> + </div> + </div> + <div class="container"> + <div class="row"> + <div class="col-sm-12"> + + + +<div id="tour-header"> + <h2><a href="/tour/">Fluo Tour</a>: Fetching multiple cells</h2> + <p class="text-muted">Tour page 15 of 26</p> +</div> +<div id="tour-content"> + <p>Each call to get a row column results in a RPC to an Accumulo server. In the cases where there are +many row columns to get, Fluo provides more specialized get methods that make less RPC calls.</p> + +<p>Below is some example code that illustrates using these methods and shows the performance +difference. The example code performs the following task.</p> + +<ul> + <li>In a single transaction, generates 100 rows each with 100 columns such that each row has the same +columns. Uses integers for the row and columns names.</li> + <li>Gets 100 columns from a single row in the following ways. Times each way. + <ul> + <li>In a loop calls <a href="/apidocs/fluo/1.0.0-beta-2/org/apache/fluo/api/client/SnapshotBase.html#gets-java.lang.CharSequence-org.apache.fluo.api.data.Column-">gets(CharSequence, Column)</a>.</li> + <li>Calls <a href="/apidocs/fluo/1.0.0-beta-2/org/apache/fluo/api/client/SnapshotBase.html#gets-java.lang.CharSequence-java.util.Set-">gets(CharSequence, Set<Column>)</a> once</li> + </ul> + </li> + <li>Gets 100 columns from 3 rows in the following ways. Times each way. + <ul> + <li>For three rows, loops over 100 columns calling <a href="/apidocs/fluo/1.0.0-beta-2/org/apache/fluo/api/client/SnapshotBase.html#gets-java.lang.CharSequence-org.apache.fluo.api.data.Column-">gets(CharSequence, Column)</a></li> + <li>Calls <a href="/apidocs/fluo/1.0.0-beta-2/org/apache/fluo/api/client/SnapshotBase.html#gets-java.util.Collection-java.util.Set-">gets(Collection<? extends CharSequence>, Set<Column>)</a> once</li> + </ul> + </li> + <li>Generates 100 row column pairs, where each pair is a random row and a random column. Gets each</li> + <li>pair in the following ways. Times each way. + <ul> + <li>For each pair calls <a href="/apidocs/fluo/1.0.0-beta-2/org/apache/fluo/api/client/SnapshotBase.html#gets-java.lang.CharSequence-org.apache.fluo.api.data.Column-">gets(CharSequence, Column)</a></li> + <li>Calls <a href="/apidocs/fluo/1.0.0-beta-2/org/apache/fluo/api/client/SnapshotBase.html#gets-java.util.Collection-">gets(Collection<RowColumn>)</a> once</li> + </ul> + </li> +</ul> + +<p>Below is the code to perform the task mentioned above.</p> + +<div class="language-java highlighter-rouge"><pre class="highlight"><code> <span class="kd">private</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">excercise</span><span class="o">(</span><span class="n">MiniFluo</span> <span class="n">mini</span><span class="o">,</span> <span class="n">FluoClient</span> <span class="n">client</span><span class="o">)</span> <span class="o">{</span> + + <span class="n">Set</span><span class="o"><</span><span class="n">Column</span><span class="o">></span> <span class="n">columns</span> <span class="o">=</span> <span class="k">new</span> <span class="n">LinkedHashSet</span><span class="o"><>();</span> + + <span class="k">for</span><span class="o">(</span><span class="kt">int</span> <span class="n">c</span> <span class="o">=</span> <span class="mi">0</span><span class="o">;</span> <span class="n">c</span> <span class="o"><</span> <span class="mi">100</span><span class="o">;</span> <span class="n">c</span><span class="o">++)</span> <span class="o">{</span> + <span class="n">columns</span><span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="k">new</span> <span class="n">Column</span><span class="o">(</span><span class="s">"f"</span><span class="o">,</span> <span class="n">String</span><span class="o">.</span><span class="na">format</span><span class="o">(</span><span class="s">"q%04d"</span><span class="o">,</span> <span class="n">c</span><span class="o">)));</span> + <span class="o">}</span> + + <span class="k">try</span><span class="o">(</span><span class="n">Transaction</span> <span class="n">tx</span> <span class="o">=</span> <span class="n">client</span><span class="o">.</span><span class="na">newTransaction</span><span class="o">())</span> <span class="o">{</span> + <span class="kt">int</span> <span class="n">value</span> <span class="o">=</span> <span class="mi">0</span><span class="o">;</span> + <span class="k">for</span><span class="o">(</span><span class="kt">int</span> <span class="n">r</span> <span class="o">=</span> <span class="mi">0</span><span class="o">;</span> <span class="n">r</span> <span class="o"><</span> <span class="mi">100</span><span class="o">;</span> <span class="n">r</span><span class="o">++)</span> <span class="o">{</span> + <span class="n">String</span> <span class="n">row</span> <span class="o">=</span> <span class="n">String</span><span class="o">.</span><span class="na">format</span><span class="o">(</span><span class="s">"r%04d"</span><span class="o">,</span> <span class="n">r</span><span class="o">);</span> + <span class="k">for</span> <span class="o">(</span><span class="n">Column</span> <span class="n">column</span> <span class="o">:</span> <span class="n">columns</span><span class="o">)</span> <span class="o">{</span> + <span class="n">tx</span><span class="o">.</span><span class="na">set</span><span class="o">(</span><span class="n">row</span><span class="o">,</span> <span class="n">column</span><span class="o">,</span> <span class="n">value</span><span class="o">+</span><span class="s">""</span><span class="o">);</span> + <span class="n">value</span><span class="o">++;</span> + <span class="o">}</span> + <span class="o">}</span> + + <span class="n">tx</span><span class="o">.</span><span class="na">commit</span><span class="o">();</span> + <span class="o">}</span> + + <span class="c1">//fetch multiple columns from a single row</span> + <span class="k">try</span><span class="o">(</span><span class="n">Snapshot</span> <span class="n">snap</span> <span class="o">=</span> <span class="n">client</span><span class="o">.</span><span class="na">newSnapshot</span><span class="o">())</span> <span class="o">{</span> + <span class="n">String</span> <span class="n">row</span> <span class="o">=</span> <span class="n">String</span><span class="o">.</span><span class="na">format</span><span class="o">(</span><span class="s">"r%04d"</span><span class="o">,</span> <span class="mi">42</span><span class="o">);</span> + + <span class="kt">long</span> <span class="n">t1</span> <span class="o">=</span> <span class="n">System</span><span class="o">.</span><span class="na">currentTimeMillis</span><span class="o">();</span> + + <span class="k">for</span> <span class="o">(</span><span class="n">Column</span> <span class="n">column</span> <span class="o">:</span> <span class="n">columns</span><span class="o">)</span> <span class="o">{</span> + <span class="n">snap</span><span class="o">.</span><span class="na">gets</span><span class="o">(</span><span class="n">row</span><span class="o">,</span> <span class="n">column</span><span class="o">);</span> + <span class="o">}</span> + + <span class="kt">long</span> <span class="n">t2</span> <span class="o">=</span> <span class="n">System</span><span class="o">.</span><span class="na">currentTimeMillis</span><span class="o">();</span> + + <span class="n">snap</span><span class="o">.</span><span class="na">gets</span><span class="o">(</span><span class="n">row</span><span class="o">,</span> <span class="n">columns</span><span class="o">);</span> + + <span class="kt">long</span> <span class="n">t3</span> <span class="o">=</span> <span class="n">System</span><span class="o">.</span><span class="na">currentTimeMillis</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">"test1 time 1:%d time2:%d\n"</span><span class="o">,(</span><span class="n">t2</span><span class="o">-</span><span class="n">t1</span><span class="o">),(</span><span class="n">t3</span><span class="o">-</span><span class="n">t2</span><span class="o">));</span> + <span class="o">}</span> + + + <span class="c1">//fetch the same columns from multiple rows</span> + <span class="k">try</span><span class="o">(</span><span class="n">Snapshot</span> <span class="n">snap</span> <span class="o">=</span> <span class="n">client</span><span class="o">.</span><span class="na">newSnapshot</span><span class="o">())</span> <span class="o">{</span> + <span class="n">List</span><span class="o"><</span><span class="n">String</span><span class="o">></span> <span class="n">rows</span> <span class="o">=</span> <span class="n">Arrays</span><span class="o">.</span><span class="na">asList</span><span class="o">(</span><span class="n">String</span><span class="o">.</span><span class="na">format</span><span class="o">(</span><span class="s">"r%04d"</span><span class="o">,</span> <span class="mi">42</span><span class="o">),</span> + <span class="n">String</span><span class="o">.</span><span class="na">format</span><span class="o">(</span><span class="s">"r%04d"</span><span class="o">,</span> <span class="mi">21</span><span class="o">),</span> + <span class="n">String</span><span class="o">.</span><span class="na">format</span><span class="o">(</span><span class="s">"r%04d"</span><span class="o">,</span> <span class="mi">84</span><span class="o">));</span> + + <span class="kt">long</span> <span class="n">t1</span> <span class="o">=</span> <span class="n">System</span><span class="o">.</span><span class="na">currentTimeMillis</span><span class="o">();</span> + + <span class="k">for</span> <span class="o">(</span><span class="n">String</span> <span class="n">row</span> <span class="o">:</span> <span class="n">rows</span><span class="o">)</span> <span class="o">{</span> + <span class="k">for</span> <span class="o">(</span><span class="n">Column</span> <span class="n">column</span> <span class="o">:</span> <span class="n">columns</span><span class="o">)</span> <span class="o">{</span> + <span class="n">snap</span><span class="o">.</span><span class="na">gets</span><span class="o">(</span><span class="n">row</span><span class="o">,</span> <span class="n">column</span><span class="o">);</span> + <span class="o">}</span> + <span class="o">}</span> + + <span class="kt">long</span> <span class="n">t2</span> <span class="o">=</span> <span class="n">System</span><span class="o">.</span><span class="na">currentTimeMillis</span><span class="o">();</span> + + <span class="n">snap</span><span class="o">.</span><span class="na">gets</span><span class="o">(</span><span class="n">rows</span><span class="o">,</span> <span class="n">columns</span><span class="o">);</span> + + <span class="kt">long</span> <span class="n">t3</span> <span class="o">=</span> <span class="n">System</span><span class="o">.</span><span class="na">currentTimeMillis</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">"test2 time 1:%d time2:%d\n"</span><span class="o">,(</span><span class="n">t2</span><span class="o">-</span><span class="n">t1</span><span class="o">),(</span><span class="n">t3</span><span class="o">-</span><span class="n">t2</span><span class="o">));</span> + <span class="o">}</span> + + <span class="c1">//fetch different columns from different rows</span> + <span class="k">try</span><span class="o">(</span><span class="n">Snapshot</span> <span class="n">snap</span> <span class="o">=</span> <span class="n">client</span><span class="o">.</span><span class="na">newSnapshot</span><span class="o">())</span> <span class="o">{</span> + <span class="n">Random</span> <span class="n">rand</span> <span class="o">=</span> <span class="k">new</span> <span class="n">Random</span><span class="o">();</span> + <span class="c1">//generate the row columns to fetch</span> + <span class="n">List</span><span class="o"><</span><span class="n">RowColumn</span><span class="o">></span> <span class="n">rowcols</span> <span class="o">=</span> <span class="k">new</span> <span class="n">ArrayList</span><span class="o"><>();</span> + <span class="k">for</span><span class="o">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="o">;</span> <span class="n">i</span> <span class="o"><</span> <span class="mi">100</span><span class="o">;</span> <span class="n">i</span><span class="o">++)</span> <span class="o">{</span> + <span class="n">String</span> <span class="n">row</span> <span class="o">=</span> <span class="n">String</span><span class="o">.</span><span class="na">format</span><span class="o">(</span><span class="s">"r%04d"</span><span class="o">,</span> <span class="n">rand</span><span class="o">.</span><span class="na">nextInt</span><span class="o">(</span><span class="mi">100</span><span class="o">));</span> + <span class="n">Column</span> <span class="n">col</span> <span class="o">=</span> <span class="k">new</span> <span class="n">Column</span><span class="o">(</span><span class="s">"f"</span><span class="o">,</span> <span class="n">String</span><span class="o">.</span><span class="na">format</span><span class="o">(</span><span class="s">"q%04d"</span><span class="o">,</span> <span class="n">rand</span><span class="o">.</span><span class="na">nextInt</span><span class="o">(</span><span class="mi">100</span><span class="o">)));</span> + <span class="n">rowcols</span><span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="k">new</span> <span class="n">RowColumn</span><span class="o">(</span><span class="n">row</span><span class="o">,</span> <span class="n">col</span><span class="o">));</span> + <span class="o">}</span> + + <span class="kt">long</span> <span class="n">t1</span> <span class="o">=</span> <span class="n">System</span><span class="o">.</span><span class="na">currentTimeMillis</span><span class="o">();</span> + + <span class="k">for</span> <span class="o">(</span><span class="n">RowColumn</span> <span class="n">rowColumn</span> <span class="o">:</span> <span class="n">rowcols</span><span class="o">)</span> <span class="o">{</span> + <span class="n">snap</span><span class="o">.</span><span class="na">get</span><span class="o">(</span><span class="n">rowColumn</span><span class="o">.</span><span class="na">getRow</span><span class="o">(),</span> <span class="n">rowColumn</span><span class="o">.</span><span class="na">getColumn</span><span class="o">());</span> + <span class="o">}</span> + + <span class="kt">long</span> <span class="n">t2</span> <span class="o">=</span> <span class="n">System</span><span class="o">.</span><span class="na">currentTimeMillis</span><span class="o">();</span> + + <span class="n">snap</span><span class="o">.</span><span class="na">gets</span><span class="o">(</span><span class="n">rowcols</span><span class="o">);</span> + + <span class="kt">long</span> <span class="n">t3</span> <span class="o">=</span> <span class="n">System</span><span class="o">.</span><span class="na">currentTimeMillis</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">"test3 time 1:%d time2:%d\n"</span><span class="o">,(</span><span class="n">t2</span><span class="o">-</span><span class="n">t1</span><span class="o">),(</span><span class="n">t3</span><span class="o">-</span><span class="n">t2</span><span class="o">));</span> + <span class="o">}</span> + <span class="o">}</span> +</code></pre> +</div> + +<p>The program above outputs :</p> + +<div class="highlighter-rouge"><pre class="highlight"><code>test1 time 1:294 time2:13 +test2 time 1:651 time2:25 +test3 time 1:153 time2:7 +</code></pre> +</div> + + +</div> + +<script> +document.body.onkeyup = function(e){ + +if (e.keyCode == '37') { window.location = '/tour/scanning-code/'; } + + + +if (e.keyCode == '39') { window.location = '/tour/loader-executer/'; } + +}; +</script> + +<div class="text-center"> + + <h2> + + <a href="/tour/scanning-code/"><</a> + + + 15 / 26 + + <a href="/tour/loader-executer/">></a> + + </h2> +</div> + + </div> + </div> + <hr> + <div class="row footer"> + <div class="col-sm-12 text-center"> + <div class="center-block"> + <a href="https://apache.org"><img src="/resources/feather.png" alt="Apache"></a> + Copyright © 2016 The Apache Software Foundation. Licensed under the <a href="https://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a> + </div> + </div> + </div> + </div> + <script src="/javascripts/jquery.min.js"></script> + <script src="/javascripts/bootstrap.min.js"></script> + <!-- Place your <script> tags here. --> + +<!-- Google Analytics --> +<script> + (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){ + (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o), + m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m) + })(window,document,'script','https://www.google-analytics.com/analytics.js','ga'); + + ga('create', 'UA-55360307-1', 'auto'); + ga('send', 'pageview'); + +</script> + + </body> +</html>
http://git-wip-us.apache.org/repos/asf/incubator-fluo-website/blob/76022205/tour/observer_example/index.html ---------------------------------------------------------------------- diff --git a/tour/observer_example/index.html b/tour/observer_example/index.html new file mode 100644 index 0000000..06514ed --- /dev/null +++ b/tour/observer_example/index.html @@ -0,0 +1,217 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <meta http-equiv="X-UA-Compatible" content="IE=edge"> + <meta name="viewport" content="width=device-width, initial-scale=1"> + <link rel="stylesheet" href="/stylesheets/fluo.css"> + <link rel="stylesheet" type="text/css" href="https://fonts.googleapis.com/css?family=Montserrat:700,400"> + <link rel="stylesheet" type="text/css" href="https://fonts.googleapis.com/css?family=Merriweather"> + <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.2.0/css/font-awesome.min.css" > + <link rel="canonical" href="http://fluo.io/tour/observer_example/"> + <link rel="icon" type="image/png" href="/resources/favicon.png"> + <title>Observer Example | Apache Fluo</title> + <!--[if lt IE 9]> + <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script> + <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script> + <![endif]--> + </head> + <body> + <div id="fluo-nav" class="navbar navbar-default navbar-static-top"> + <div class="container"> + <div class="navbar-header"> + <div class="navbar-toggle-wrapper visible-xs"> + <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".js-navbar-collapse"> + <span class="icon-bar"></span> + <span class="icon-bar"></span> + <span class="icon-bar"></span> + </button> + </div> + <a href="/" class="navbar-brand"><img src="/resources/fluo-logo.png" alt="Apache Fluo"></a> + </div> + <div class="collapse navbar-collapse js-navbar-collapse" style="margin-top: 20px"> + <ul class="navbar-nav nav"> + <li><a href="/docs/">Documentation</a></li> + <li><a href="/download/">Download</a></li> + <li class="dropdown"> + <a class="dropdown-toggle" data-toggle="dropdown" href="#">Community<span class="caret"></span></a> + <ul class="dropdown-menu"> + <li><a href="/getinvolved/">Get Involved</a></li> + <li><a href="/blog/">Blog</a></li> + <li><a href="/people/">People</a></li> + <li><a href="/related-projects/">Related Projects</a></li> + <li><a href="/poweredby/">Powered By</a></li> + </ul> + </li> + <li class="dropdown"> + <a class="dropdown-toggle" data-toggle="dropdown" href="#">Contributing<span class="caret"></span></a> + <ul class="dropdown-menu"> + <li><a href="/how-to-contribute/">How To Contribute</a></li> + <li><a href="/release-process/">Release Process</a></li> + </ul> + </li> + </ul> + <ul class="navbar-nav nav navbar-right"> + <li class="dropdown"> + <a class="dropdown-toggle" data-toggle="dropdown" href="#">Apache Software Foundation<span class="caret"></span></a> + <ul class="dropdown-menu"> + <li><a href="https://www.apache.org">Apache Homepage</a></li> + <li><a href="https://www.apache.org/licenses/LICENSE-2.0">License</a></li> + <li><a href="https://www.apache.org/foundation/sponsorship">Sponsorship</i></a></li> + <li><a href="https://www.apache.org/security">Security</a></li> + <li><a href="https://www.apache.org/foundation/thanks">Thanks</a></li> + <li><a href="https://www.apache.org/foundation/policies/conduct">Code of Conduct</a></li> + </ul> + </li> + </ul> + </div> + </div> + </div> + <div class="container"> + <div class="row"> + <div class="col-sm-12"> + + + +<div id="tour-header"> + <h2><a href="/tour/">Fluo Tour</a>: Observer Example</h2> + <p class="text-muted">Tour page 18 of 26</p> +</div> +<div id="tour-content"> + <p>The following code shows how to setup and trigger an observer. The observer is triggered when the +column <em>obs:data</em> is changed.</p> + +<div class="language-java highlighter-rouge"><pre class="highlight"><code> <span class="kd">public</span> <span class="kd">static</span> <span class="kd">final</span> <span class="n">Column</span> <span class="n">OBSERVED_COL</span> <span class="o">=</span> <span class="k">new</span> <span class="n">Column</span><span class="o">(</span><span class="s">"obs"</span><span class="o">,</span><span class="s">"data"</span><span class="o">);</span> + <span class="kd">public</span> <span class="kd">static</span> <span class="kd">final</span> <span class="n">Column</span> <span class="n">INVERT_COL</span> <span class="o">=</span> <span class="k">new</span> <span class="n">Column</span><span class="o">(</span><span class="s">"inv"</span><span class="o">,</span><span class="s">"data"</span><span class="o">);</span> + + <span class="kd">public</span> <span class="kd">static</span> <span class="kd">class</span> <span class="nc">MyObserver</span> <span class="kd">extends</span> <span class="n">AbstractObserver</span> <span class="o">{</span> + + <span class="nd">@Override</span> + <span class="kd">public</span> <span class="kt">void</span> <span class="nf">process</span><span class="o">(</span><span class="n">TransactionBase</span> <span class="n">tx</span><span class="o">,</span> <span class="n">Bytes</span> <span class="n">row</span><span class="o">,</span> <span class="n">Column</span> <span class="n">col</span><span class="o">)</span> <span class="kd">throws</span> <span class="n">Exception</span> <span class="o">{</span> + <span class="c1">//invert column and value</span> + <span class="n">Bytes</span> <span class="n">value</span> <span class="o">=</span> <span class="n">tx</span><span class="o">.</span><span class="na">get</span><span class="o">(</span><span class="n">row</span><span class="o">,</span> <span class="n">col</span><span class="o">);</span> + <span class="n">tx</span><span class="o">.</span><span class="na">set</span><span class="o">(</span><span class="n">value</span><span class="o">,</span> <span class="n">INVERT_COL</span><span class="o">,</span> <span class="n">row</span><span class="o">);</span> + <span class="o">}</span> + + <span class="nd">@Override</span> + <span class="kd">public</span> <span class="n">ObservedColumn</span> <span class="nf">getObservedColumn</span><span class="o">()</span> <span class="o">{</span> + <span class="k">return</span> <span class="k">new</span> <span class="nf">ObservedColumn</span><span class="o">(</span><span class="n">OBSERVED_COL</span><span class="o">,</span> <span class="n">NotificationType</span><span class="o">.</span><span class="na">STRONG</span><span class="o">);</span> + <span class="o">}</span> + <span class="o">}</span> + + <span class="kd">private</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">preInit</span><span class="o">(</span><span class="n">FluoConfiguration</span> <span class="n">fluoConfig</span><span class="o">)</span> <span class="o">{</span> + <span class="c1">//configure Fluo to use MyObserver before initialization</span> + <span class="n">fluoConfig</span><span class="o">.</span><span class="na">addObserver</span><span class="o">(</span><span class="k">new</span> <span class="n">ObserverSpecification</span><span class="o">(</span><span class="n">MyObserver</span><span class="o">.</span><span class="na">class</span><span class="o">.</span><span class="na">getName</span><span class="o">()));</span> + <span class="o">}</span> + + <span class="kd">private</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">excercise</span><span class="o">(</span><span class="n">MiniFluo</span> <span class="n">mini</span><span class="o">,</span> <span class="n">FluoClient</span> <span class="n">client</span><span class="o">)</span> <span class="o">{</span> + <span class="k">try</span><span class="o">(</span><span class="n">Transaction</span> <span class="n">tx1</span> <span class="o">=</span> <span class="n">client</span><span class="o">.</span><span class="na">newTransaction</span><span class="o">())</span> <span class="o">{</span> + <span class="n">tx1</span><span class="o">.</span><span class="na">set</span><span class="o">(</span><span class="s">"kerbalnaut0001"</span><span class="o">,</span> <span class="n">OBSERVED_COL</span><span class="o">,</span> <span class="s">"Jebediah"</span><span class="o">);</span> + <span class="n">tx1</span><span class="o">.</span><span class="na">commit</span><span class="o">();</span> + <span class="o">}</span> + + <span class="k">try</span><span class="o">(</span><span class="n">Transaction</span> <span class="n">tx2</span> <span class="o">=</span> <span class="n">client</span><span class="o">.</span><span class="na">newTransaction</span><span class="o">())</span> <span class="o">{</span> + <span class="n">tx2</span><span class="o">.</span><span class="na">set</span><span class="o">(</span><span class="s">"kerbalnaut0002"</span><span class="o">,</span> <span class="n">OBSERVED_COL</span><span class="o">,</span> <span class="s">"Bill"</span><span class="o">);</span> + <span class="n">tx2</span><span class="o">.</span><span class="na">commit</span><span class="o">();</span> + <span class="o">}</span> + + <span class="n">mini</span><span class="o">.</span><span class="na">waitForObservers</span><span class="o">();</span> + + <span class="k">try</span><span class="o">(</span><span class="n">Snapshot</span> <span class="n">snap</span> <span class="o">=</span> <span class="n">client</span><span class="o">.</span><span class="na">newSnapshot</span><span class="o">())</span> <span class="o">{</span> + <span class="n">snap</span><span class="o">.</span><span class="na">scanner</span><span class="o">().</span><span class="na">build</span><span class="o">().</span><span class="na">forEach</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="n">println</span><span class="o">);</span> + <span class="o">}</span> + <span class="o">}</span> +</code></pre> +</div> + +<p>The code above prints :</p> + +<div class="highlighter-rouge"><pre class="highlight"><code>Bill inv data kerbalnaut0002 +Jebediah inv data kerbalnaut0001 +kerbalnaut0001 obs data Jebediah +kerbalnaut0002 obs data Bill +</code></pre> +</div> + +<p>The following events happen when this code is run.</p> + +<ul> + <li><em>tx1</em> modifies <em>kerbalnaut0001:obs:data</em> causing <em>MyObserver</em> to run later on that row+column.</li> + <li><em>tx2</em> modifies <em>kerbalnaut0002:obs:data</em> causing <em>MyObserver</em> to run later on that row+column.</li> + <li>Later <em>MyObserver</em> is run and passed row+column <em>kerbalnaut0001:obs:data</em></li> + <li>Later <em>MyObserver</em> is run and passed row+column <em>kerbalnaut0002:obs:data</em></li> +</ul> + +<p>Observers are run in the background by Fluo threads. Fluo also creates the +transaction passed to an Observer and commits it. The transaction does not +need to call commit and can not, the TransactionBase type passed to an Observer +does not have a commit method. The framework handles committing because it +retries in case of a commit exception.</p> + +<p>Since observers are run in the background, you never know when they will run. +For testing purposes MiniFluo provides the waitForObservers() method that is +called above. This method waits for all notifications to be processed by +observers.</p> + +<p>There is no stand alone exercise for the Observer. Hands on experience with it can be obtained by +completing the <a href="/tour/exercise-1/">word count exercise</a> which is the next step in the tour.</p> + + +</div> + +<script> +document.body.onkeyup = function(e){ + +if (e.keyCode == '37') { window.location = '/tour/observers/'; } + + + +if (e.keyCode == '39') { window.location = '/tour/exercise-1/'; } + +}; +</script> + +<div class="text-center"> + + <h2> + + <a href="/tour/observers/"><</a> + + + 18 / 26 + + <a href="/tour/exercise-1/">></a> + + </h2> +</div> + + </div> + </div> + <hr> + <div class="row footer"> + <div class="col-sm-12 text-center"> + <div class="center-block"> + <a href="https://apache.org"><img src="/resources/feather.png" alt="Apache"></a> + Copyright © 2016 The Apache Software Foundation. Licensed under the <a href="https://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a> + </div> + </div> + </div> + </div> + <script src="/javascripts/jquery.min.js"></script> + <script src="/javascripts/bootstrap.min.js"></script> + <!-- Place your <script> tags here. --> + +<!-- Google Analytics --> +<script> + (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){ + (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o), + m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m) + })(window,document,'script','https://www.google-analytics.com/analytics.js','ga'); + + ga('create', 'UA-55360307-1', 'auto'); + ga('send', 'pageview'); + +</script> + + </body> +</html> http://git-wip-us.apache.org/repos/asf/incubator-fluo-website/blob/76022205/tour/observers/index.html ---------------------------------------------------------------------- diff --git a/tour/observers/index.html b/tour/observers/index.html new file mode 100644 index 0000000..1c4b974 --- /dev/null +++ b/tour/observers/index.html @@ -0,0 +1,163 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <meta http-equiv="X-UA-Compatible" content="IE=edge"> + <meta name="viewport" content="width=device-width, initial-scale=1"> + <link rel="stylesheet" href="/stylesheets/fluo.css"> + <link rel="stylesheet" type="text/css" href="https://fonts.googleapis.com/css?family=Montserrat:700,400"> + <link rel="stylesheet" type="text/css" href="https://fonts.googleapis.com/css?family=Merriweather"> + <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.2.0/css/font-awesome.min.css" > + <link rel="canonical" href="http://fluo.io/tour/observers/"> + <link rel="icon" type="image/png" href="/resources/favicon.png"> + <title>Observer Concepts | Apache Fluo</title> + <!--[if lt IE 9]> + <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script> + <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script> + <![endif]--> + </head> + <body> + <div id="fluo-nav" class="navbar navbar-default navbar-static-top"> + <div class="container"> + <div class="navbar-header"> + <div class="navbar-toggle-wrapper visible-xs"> + <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".js-navbar-collapse"> + <span class="icon-bar"></span> + <span class="icon-bar"></span> + <span class="icon-bar"></span> + </button> + </div> + <a href="/" class="navbar-brand"><img src="/resources/fluo-logo.png" alt="Apache Fluo"></a> + </div> + <div class="collapse navbar-collapse js-navbar-collapse" style="margin-top: 20px"> + <ul class="navbar-nav nav"> + <li><a href="/docs/">Documentation</a></li> + <li><a href="/download/">Download</a></li> + <li class="dropdown"> + <a class="dropdown-toggle" data-toggle="dropdown" href="#">Community<span class="caret"></span></a> + <ul class="dropdown-menu"> + <li><a href="/getinvolved/">Get Involved</a></li> + <li><a href="/blog/">Blog</a></li> + <li><a href="/people/">People</a></li> + <li><a href="/related-projects/">Related Projects</a></li> + <li><a href="/poweredby/">Powered By</a></li> + </ul> + </li> + <li class="dropdown"> + <a class="dropdown-toggle" data-toggle="dropdown" href="#">Contributing<span class="caret"></span></a> + <ul class="dropdown-menu"> + <li><a href="/how-to-contribute/">How To Contribute</a></li> + <li><a href="/release-process/">Release Process</a></li> + </ul> + </li> + </ul> + <ul class="navbar-nav nav navbar-right"> + <li class="dropdown"> + <a class="dropdown-toggle" data-toggle="dropdown" href="#">Apache Software Foundation<span class="caret"></span></a> + <ul class="dropdown-menu"> + <li><a href="https://www.apache.org">Apache Homepage</a></li> + <li><a href="https://www.apache.org/licenses/LICENSE-2.0">License</a></li> + <li><a href="https://www.apache.org/foundation/sponsorship">Sponsorship</i></a></li> + <li><a href="https://www.apache.org/security">Security</a></li> + <li><a href="https://www.apache.org/foundation/thanks">Thanks</a></li> + <li><a href="https://www.apache.org/foundation/policies/conduct">Code of Conduct</a></li> + </ul> + </li> + </ul> + </div> + </div> + </div> + <div class="container"> + <div class="row"> + <div class="col-sm-12"> + + + +<div id="tour-header"> + <h2><a href="/tour/">Fluo Tour</a>: Observer Concepts</h2> + <p class="text-muted">Tour page 17 of 26</p> +</div> +<div id="tour-content"> + <p>Fluo supports complex processing by running user provided code in Observers. Observers are triggered +by notifications. An Observer requests that the system run it when a certain column is modified. When +another transaction modifies an observed column, it will persist a notification that later causes +the Observer to run. When an Observer is run, its provided with the row and column that caused it +to run along with a transaction. Fluo worker processes running across a cluster will execute +Observers.</p> + +<p>Since all transactions need to know which columns trigger observers, observers must be registered +with Fluo at initialization time.</p> + +<p>Fluo supports two type of notifications :</p> + +<ul> + <li><strong>Strong notifications:</strong> guarantee an observer will run at most once when a column is modified. +If multiple transactions modify an observed row+column before an observer runs, it will only run +once. It will not run once for each modification.</li> + <li><strong>Weak notifications:</strong> cause an observer to run at least once. Observers may run multiple times +and/or concurrently based on a single weak notification. In order to guarantee strong +notifications run an observer at most once, strong notifications are part of the transaction +model. Therefore a strong notification can cause transaction collisions. Weak notifications are +not transactional and will not cause collisions. Therefore in situations where many transactions +are notifying a row+column concurrently, using weak notifications is best.</li> +</ul> + + +</div> + +<script> +document.body.onkeyup = function(e){ + +if (e.keyCode == '37') { window.location = '/tour/loader-executer/'; } + + + +if (e.keyCode == '39') { window.location = '/tour/observer_example/'; } + +}; +</script> + +<div class="text-center"> + + <h2> + + <a href="/tour/loader-executer/"><</a> + + + 17 / 26 + + <a href="/tour/observer_example/">></a> + + </h2> +</div> + + </div> + </div> + <hr> + <div class="row footer"> + <div class="col-sm-12 text-center"> + <div class="center-block"> + <a href="https://apache.org"><img src="/resources/feather.png" alt="Apache"></a> + Copyright © 2016 The Apache Software Foundation. Licensed under the <a href="https://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a> + </div> + </div> + </div> + </div> + <script src="/javascripts/jquery.min.js"></script> + <script src="/javascripts/bootstrap.min.js"></script> + <!-- Place your <script> tags here. --> + +<!-- Google Analytics --> +<script> + (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){ + (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o), + m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m) + })(window,document,'script','https://www.google-analytics.com/analytics.js','ga'); + + ga('create', 'UA-55360307-1', 'auto'); + ga('send', 'pageview'); + +</script> + + </body> +</html> http://git-wip-us.apache.org/repos/asf/incubator-fluo-website/blob/76022205/tour/recipes/index.html ---------------------------------------------------------------------- diff --git a/tour/recipes/index.html b/tour/recipes/index.html new file mode 100644 index 0000000..a510bc3 --- /dev/null +++ b/tour/recipes/index.html @@ -0,0 +1,137 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <meta http-equiv="X-UA-Compatible" content="IE=edge"> + <meta name="viewport" content="width=device-width, initial-scale=1"> + <link rel="stylesheet" href="/stylesheets/fluo.css"> + <link rel="stylesheet" type="text/css" href="https://fonts.googleapis.com/css?family=Montserrat:700,400"> + <link rel="stylesheet" type="text/css" href="https://fonts.googleapis.com/css?family=Merriweather"> + <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.2.0/css/font-awesome.min.css" > + <link rel="canonical" href="http://fluo.io/tour/recipes/"> + <link rel="icon" type="image/png" href="/resources/favicon.png"> + <title>Fluo Recipes | Apache Fluo</title> + <!--[if lt IE 9]> + <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script> + <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script> + <![endif]--> + </head> + <body> + <div id="fluo-nav" class="navbar navbar-default navbar-static-top"> + <div class="container"> + <div class="navbar-header"> + <div class="navbar-toggle-wrapper visible-xs"> + <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".js-navbar-collapse"> + <span class="icon-bar"></span> + <span class="icon-bar"></span> + <span class="icon-bar"></span> + </button> + </div> + <a href="/" class="navbar-brand"><img src="/resources/fluo-logo.png" alt="Apache Fluo"></a> + </div> + <div class="collapse navbar-collapse js-navbar-collapse" style="margin-top: 20px"> + <ul class="navbar-nav nav"> + <li><a href="/docs/">Documentation</a></li> + <li><a href="/download/">Download</a></li> + <li class="dropdown"> + <a class="dropdown-toggle" data-toggle="dropdown" href="#">Community<span class="caret"></span></a> + <ul class="dropdown-menu"> + <li><a href="/getinvolved/">Get Involved</a></li> + <li><a href="/blog/">Blog</a></li> + <li><a href="/people/">People</a></li> + <li><a href="/related-projects/">Related Projects</a></li> + <li><a href="/poweredby/">Powered By</a></li> + </ul> + </li> + <li class="dropdown"> + <a class="dropdown-toggle" data-toggle="dropdown" href="#">Contributing<span class="caret"></span></a> + <ul class="dropdown-menu"> + <li><a href="/how-to-contribute/">How To Contribute</a></li> + <li><a href="/release-process/">Release Process</a></li> + </ul> + </li> + </ul> + <ul class="navbar-nav nav navbar-right"> + <li class="dropdown"> + <a class="dropdown-toggle" data-toggle="dropdown" href="#">Apache Software Foundation<span class="caret"></span></a> + <ul class="dropdown-menu"> + <li><a href="https://www.apache.org">Apache Homepage</a></li> + <li><a href="https://www.apache.org/licenses/LICENSE-2.0">License</a></li> + <li><a href="https://www.apache.org/foundation/sponsorship">Sponsorship</i></a></li> + <li><a href="https://www.apache.org/security">Security</a></li> + <li><a href="https://www.apache.org/foundation/thanks">Thanks</a></li> + <li><a href="https://www.apache.org/foundation/policies/conduct">Code of Conduct</a></li> + </ul> + </li> + </ul> + </div> + </div> + </div> + <div class="container"> + <div class="row"> + <div class="col-sm-12"> + + + +<div id="tour-header"> + <h2><a href="/tour/">Fluo Tour</a>: Fluo Recipes</h2> + <p class="text-muted">Tour page 26 of 26</p> +</div> +<div id="tour-content"> + <p>Coming soon, a tour of <a href="https://github.com/apache/fluo-recipes">Fluo Recipes</a>.</p> + + +</div> + +<script> +document.body.onkeyup = function(e){ + +if (e.keyCode == '37') { window.location = '/tour/mem-self-ntfy-code/'; } + + + +}; +</script> + +<div class="text-center"> + + <h2> + + <a href="/tour/mem-self-ntfy-code/"><</a> + + + 26 / 26 + + </h2> +</div> + + </div> + </div> + <hr> + <div class="row footer"> + <div class="col-sm-12 text-center"> + <div class="center-block"> + <a href="https://apache.org"><img src="/resources/feather.png" alt="Apache"></a> + Copyright © 2016 The Apache Software Foundation. Licensed under the <a href="https://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a> + </div> + </div> + </div> + </div> + <script src="/javascripts/jquery.min.js"></script> + <script src="/javascripts/bootstrap.min.js"></script> + <!-- Place your <script> tags here. --> + +<!-- Google Analytics --> +<script> + (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){ + (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o), + m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m) + })(window,document,'script','https://www.google-analytics.com/analytics.js','ga'); + + ga('create', 'UA-55360307-1', 'auto'); + ga('send', 'pageview'); + +</script> + + </body> +</html> http://git-wip-us.apache.org/repos/asf/incubator-fluo-website/blob/76022205/tour/row-locking/index.html ---------------------------------------------------------------------- diff --git a/tour/row-locking/index.html b/tour/row-locking/index.html new file mode 100644 index 0000000..04abddd --- /dev/null +++ b/tour/row-locking/index.html @@ -0,0 +1,237 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <meta http-equiv="X-UA-Compatible" content="IE=edge"> + <meta name="viewport" content="width=device-width, initial-scale=1"> + <link rel="stylesheet" href="/stylesheets/fluo.css"> + <link rel="stylesheet" type="text/css" href="https://fonts.googleapis.com/css?family=Montserrat:700,400"> + <link rel="stylesheet" type="text/css" href="https://fonts.googleapis.com/css?family=Merriweather"> + <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.2.0/css/font-awesome.min.css" > + <link rel="canonical" href="http://fluo.io/tour/row-locking/"> + <link rel="icon" type="image/png" href="/resources/favicon.png"> + <title>Row Locking | Apache Fluo</title> + <!--[if lt IE 9]> + <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script> + <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script> + <![endif]--> + </head> + <body> + <div id="fluo-nav" class="navbar navbar-default navbar-static-top"> + <div class="container"> + <div class="navbar-header"> + <div class="navbar-toggle-wrapper visible-xs"> + <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".js-navbar-collapse"> + <span class="icon-bar"></span> + <span class="icon-bar"></span> + <span class="icon-bar"></span> + </button> + </div> + <a href="/" class="navbar-brand"><img src="/resources/fluo-logo.png" alt="Apache Fluo"></a> + </div> + <div class="collapse navbar-collapse js-navbar-collapse" style="margin-top: 20px"> + <ul class="navbar-nav nav"> + <li><a href="/docs/">Documentation</a></li> + <li><a href="/download/">Download</a></li> + <li class="dropdown"> + <a class="dropdown-toggle" data-toggle="dropdown" href="#">Community<span class="caret"></span></a> + <ul class="dropdown-menu"> + <li><a href="/getinvolved/">Get Involved</a></li> + <li><a href="/blog/">Blog</a></li> + <li><a href="/people/">People</a></li> + <li><a href="/related-projects/">Related Projects</a></li> + <li><a href="/poweredby/">Powered By</a></li> + </ul> + </li> + <li class="dropdown"> + <a class="dropdown-toggle" data-toggle="dropdown" href="#">Contributing<span class="caret"></span></a> + <ul class="dropdown-menu"> + <li><a href="/how-to-contribute/">How To Contribute</a></li> + <li><a href="/release-process/">Release Process</a></li> + </ul> + </li> + </ul> + <ul class="navbar-nav nav navbar-right"> + <li class="dropdown"> + <a class="dropdown-toggle" data-toggle="dropdown" href="#">Apache Software Foundation<span class="caret"></span></a> + <ul class="dropdown-menu"> + <li><a href="https://www.apache.org">Apache Homepage</a></li> + <li><a href="https://www.apache.org/licenses/LICENSE-2.0">License</a></li> + <li><a href="https://www.apache.org/foundation/sponsorship">Sponsorship</i></a></li> + <li><a href="https://www.apache.org/security">Security</a></li> + <li><a href="https://www.apache.org/foundation/thanks">Thanks</a></li> + <li><a href="https://www.apache.org/foundation/policies/conduct">Code of Conduct</a></li> + </ul> + </li> + </ul> + </div> + </div> + </div> + <div class="container"> + <div class="row"> + <div class="col-sm-12"> + + + +<div id="tour-header"> + <h2><a href="/tour/">Fluo Tour</a>: Row Locking</h2> + <p class="text-muted">Tour page 20 of 26</p> +</div> +<div id="tour-content"> + <p>Fluo relies on Accumuloâs conditional mutations to implement cross node +transactions. Conditional mutations lock entire rows on the server side when +checking conditions. These row locks can impact the performance of your +transactions, so itâs something to be aware of when designing a schema.</p> + +<p>For example, the following illustration shows multiple Fluo clients executing +transactions. These transactions update different columns in the same row. +The transactions will not collide, however they may end up waiting on each +other because Accumulo locks <code class="highlighter-rouge">Row 1</code> to process each update.</p> + +<!-- source for figure : https://docs.google.com/drawings/d/1CpUBE5kEGHoZUCUdO9MMyHksgZHylAUbQVJYlrp-DF0/edit?usp=sharing --> +<p><img src="/resources/tour/RowLocking.png" alt="fig1" /></p> + +<p>Determining whether this problem will impact you depends on your schema and the +probability of concurrent updates. Mitigating action is only needed if the +following criteria are met.</p> + +<ul> + <li>Many transactions will update separate columns in a row.</li> + <li>Those transactions are very likely to run concurrently.</li> +</ul> + +<p>If both of the conditions above are met then transactions will likely wait +unnecessarily. One simple way to avoid the wait is to move some of the +information that was in the column into the row. In the example above the +information in the column could be appended to the row. Then the transactions +would be updating rows <code class="highlighter-rouge">Row 1:U</code>, <code class="highlighter-rouge">Row 1:V</code>, <code class="highlighter-rouge">Row 1:W</code>, and <code class="highlighter-rouge">Row 1:X</code>. Since +these are separate rows, lock contention is avoided in Accumulo tablet servers.</p> + +<h2 id="example">Example</h2> + +<p>The following code demonstrate the impact of schema design on performance. The +code adds lots of edges to a single node in a graph using many transactions and +threads. All of the edges are added to a single row.</p> + +<p>These performance problems may not occur on a single node with a single client, +because Fluo clients batch a lot of operations related to committing. To make +the problem more apparent on a single node, the following code creates three +clients and three loaders.</p> + +<div class="language-java highlighter-rouge"><pre class="highlight"><code> <span class="kd">public</span> <span class="kd">static</span> <span class="kd">class</span> <span class="nc">EdgeLoader</span> <span class="kd">implements</span> <span class="n">Loader</span> <span class="o">{</span> + + <span class="kd">private</span> <span class="n">String</span> <span class="n">node1</span><span class="o">;</span> + <span class="kd">private</span> <span class="n">String</span> <span class="n">node2</span><span class="o">;</span> + + <span class="kd">public</span> <span class="nf">EdgeLoader</span><span class="o">(</span><span class="n">String</span> <span class="n">node1</span><span class="o">,</span> <span class="n">String</span> <span class="n">node2</span><span class="o">)</span> <span class="o">{</span> + <span class="k">this</span><span class="o">.</span><span class="na">node1</span> <span class="o">=</span> <span class="n">node1</span><span class="o">;</span> + <span class="k">this</span><span class="o">.</span><span class="na">node2</span> <span class="o">=</span> <span class="n">node2</span><span class="o">;</span> + <span class="o">}</span> + + <span class="nd">@Override</span> + <span class="kd">public</span> <span class="kt">void</span> <span class="nf">load</span><span class="o">(</span><span class="n">TransactionBase</span> <span class="n">tx</span><span class="o">,</span> <span class="n">Context</span> <span class="n">ctx</span><span class="o">)</span> <span class="kd">throws</span> <span class="n">Exception</span> <span class="o">{</span> + <span class="n">tx</span><span class="o">.</span><span class="na">set</span><span class="o">(</span><span class="n">node1</span><span class="o">,</span> <span class="k">new</span> <span class="n">Column</span><span class="o">(</span><span class="s">"edge"</span><span class="o">,</span> <span class="n">node2</span><span class="o">),</span> <span class="s">""</span><span class="o">);</span> + <span class="o">}</span> + <span class="o">}</span> + + <span class="kd">private</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">excercise</span><span class="o">(</span><span class="n">MiniFluo</span> <span class="n">mini</span><span class="o">,</span> <span class="n">FluoClient</span> <span class="n">client</span><span class="o">)</span> <span class="o">{</span> + + <span class="n">String</span> <span class="n">node1</span> <span class="o">=</span> <span class="s">"n00000"</span><span class="o">;</span> + + <span class="kt">long</span> <span class="n">t1</span> <span class="o">=</span> <span class="n">System</span><span class="o">.</span><span class="na">currentTimeMillis</span><span class="o">();</span> + + <span class="k">try</span> <span class="o">(</span><span class="n">LoaderExecutor</span> <span class="n">le1</span> <span class="o">=</span> <span class="n">client</span><span class="o">.</span><span class="na">newLoaderExecutor</span><span class="o">();</span> + <span class="n">FluoClient</span> <span class="n">client2</span> <span class="o">=</span> <span class="n">FluoFactory</span><span class="o">.</span><span class="na">newClient</span><span class="o">(</span><span class="n">mini</span><span class="o">.</span><span class="na">getClientConfiguration</span><span class="o">());</span> + <span class="n">LoaderExecutor</span> <span class="n">le2</span> <span class="o">=</span> <span class="n">client2</span><span class="o">.</span><span class="na">newLoaderExecutor</span><span class="o">();</span> + <span class="n">FluoClient</span> <span class="n">client3</span> <span class="o">=</span> <span class="n">FluoFactory</span><span class="o">.</span><span class="na">newClient</span><span class="o">(</span><span class="n">mini</span><span class="o">.</span><span class="na">getClientConfiguration</span><span class="o">());</span> + <span class="n">LoaderExecutor</span> <span class="n">le3</span> <span class="o">=</span> <span class="n">client2</span><span class="o">.</span><span class="na">newLoaderExecutor</span><span class="o">())</span> <span class="o">{</span> + + <span class="kt">int</span> <span class="n">start</span> <span class="o">=</span> <span class="mi">1</span><span class="o">;</span> + + <span class="k">for</span><span class="o">(</span><span class="n">LoaderExecutor</span> <span class="n">le</span> <span class="o">:</span> <span class="n">Arrays</span><span class="o">.</span><span class="na">asList</span><span class="o">(</span><span class="n">le1</span><span class="o">,</span> <span class="n">le2</span><span class="o">,</span> <span class="n">le3</span><span class="o">))</span> <span class="o">{</span> + <span class="k">for</span> <span class="o">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">1</span><span class="o">;</span> <span class="n">i</span> <span class="o"><</span> <span class="mi">10000</span><span class="o">;</span> <span class="n">i</span><span class="o">++)</span> <span class="o">{</span> + <span class="n">String</span> <span class="n">node2</span> <span class="o">=</span> <span class="n">String</span><span class="o">.</span><span class="na">format</span><span class="o">(</span><span class="s">"%05d"</span><span class="o">,</span> <span class="n">i</span><span class="o">+</span><span class="n">start</span><span class="o">);</span> + <span class="n">le</span><span class="o">.</span><span class="na">execute</span><span class="o">(</span><span class="k">new</span> <span class="n">EdgeLoader</span><span class="o">(</span><span class="n">node1</span><span class="o">,</span> <span class="n">node2</span><span class="o">));</span> + <span class="o">}</span> + + <span class="n">start</span><span class="o">+=</span><span class="mi">10000</span><span class="o">;</span> + <span class="o">}</span> + <span class="o">}</span> + + <span class="kt">long</span> <span class="n">t2</span> <span class="o">=</span> <span class="n">System</span><span class="o">.</span><span class="na">currentTimeMillis</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">println</span><span class="o">(</span><span class="n">t2</span> <span class="o">-</span> <span class="n">t1</span><span class="o">);</span> + <span class="o">}</span> +</code></pre> +</div> + +<p>Try running the code above and note the time. Then change the load function to +the following and run the code again. You should see a significant decrease in +the time it takes. The change below spreads the edges over many rows.</p> + +<div class="language-java highlighter-rouge"><pre class="highlight"><code> <span class="nd">@Override</span> + <span class="kd">public</span> <span class="kt">void</span> <span class="nf">load</span><span class="o">(</span><span class="n">TransactionBase</span> <span class="n">tx</span><span class="o">,</span> <span class="n">Context</span> <span class="n">ctx</span><span class="o">)</span> <span class="kd">throws</span> <span class="n">Exception</span> <span class="o">{</span> + <span class="n">tx</span><span class="o">.</span><span class="na">set</span><span class="o">(</span><span class="n">node1</span><span class="o">+</span><span class="s">":"</span><span class="o">+</span><span class="n">node2</span><span class="o">,</span> <span class="k">new</span> <span class="n">Column</span><span class="o">(</span><span class="s">"edge"</span><span class="o">,</span> <span class="s">""</span><span class="o">),</span> <span class="s">""</span><span class="o">);</span> + <span class="o">}</span> +</code></pre> +</div> + + +</div> + +<script> +document.body.onkeyup = function(e){ + +if (e.keyCode == '37') { window.location = '/tour/exercise-1/'; } + + + +if (e.keyCode == '39') { window.location = '/tour/weak-notifications/'; } + +}; +</script> + +<div class="text-center"> + + <h2> + + <a href="/tour/exercise-1/"><</a> + + + 20 / 26 + + <a href="/tour/weak-notifications/">></a> + + </h2> +</div> + + </div> + </div> + <hr> + <div class="row footer"> + <div class="col-sm-12 text-center"> + <div class="center-block"> + <a href="https://apache.org"><img src="/resources/feather.png" alt="Apache"></a> + Copyright © 2016 The Apache Software Foundation. Licensed under the <a href="https://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a> + </div> + </div> + </div> + </div> + <script src="/javascripts/jquery.min.js"></script> + <script src="/javascripts/bootstrap.min.js"></script> + <!-- Place your <script> tags here. --> + +<!-- Google Analytics --> +<script> + (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){ + (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o), + m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m) + })(window,document,'script','https://www.google-analytics.com/analytics.js','ga'); + + ga('create', 'UA-55360307-1', 'auto'); + ga('send', 'pageview'); + +</script> + + </body> +</html> http://git-wip-us.apache.org/repos/asf/incubator-fluo-website/blob/76022205/tour/scanning-code/index.html ---------------------------------------------------------------------- diff --git a/tour/scanning-code/index.html b/tour/scanning-code/index.html new file mode 100644 index 0000000..369917e --- /dev/null +++ b/tour/scanning-code/index.html @@ -0,0 +1,210 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <meta http-equiv="X-UA-Compatible" content="IE=edge"> + <meta name="viewport" content="width=device-width, initial-scale=1"> + <link rel="stylesheet" href="/stylesheets/fluo.css"> + <link rel="stylesheet" type="text/css" href="https://fonts.googleapis.com/css?family=Montserrat:700,400"> + <link rel="stylesheet" type="text/css" href="https://fonts.googleapis.com/css?family=Merriweather"> + <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.2.0/css/font-awesome.min.css" > + <link rel="canonical" href="http://fluo.io/tour/scanning-code/"> + <link rel="icon" type="image/png" href="/resources/favicon.png"> + <title>Scanning Code | Apache Fluo</title> + <!--[if lt IE 9]> + <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script> + <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script> + <![endif]--> + </head> + <body> + <div id="fluo-nav" class="navbar navbar-default navbar-static-top"> + <div class="container"> + <div class="navbar-header"> + <div class="navbar-toggle-wrapper visible-xs"> + <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".js-navbar-collapse"> + <span class="icon-bar"></span> + <span class="icon-bar"></span> + <span class="icon-bar"></span> + </button> + </div> + <a href="/" class="navbar-brand"><img src="/resources/fluo-logo.png" alt="Apache Fluo"></a> + </div> + <div class="collapse navbar-collapse js-navbar-collapse" style="margin-top: 20px"> + <ul class="navbar-nav nav"> + <li><a href="/docs/">Documentation</a></li> + <li><a href="/download/">Download</a></li> + <li class="dropdown"> + <a class="dropdown-toggle" data-toggle="dropdown" href="#">Community<span class="caret"></span></a> + <ul class="dropdown-menu"> + <li><a href="/getinvolved/">Get Involved</a></li> + <li><a href="/blog/">Blog</a></li> + <li><a href="/people/">People</a></li> + <li><a href="/related-projects/">Related Projects</a></li> + <li><a href="/poweredby/">Powered By</a></li> + </ul> + </li> + <li class="dropdown"> + <a class="dropdown-toggle" data-toggle="dropdown" href="#">Contributing<span class="caret"></span></a> + <ul class="dropdown-menu"> + <li><a href="/how-to-contribute/">How To Contribute</a></li> + <li><a href="/release-process/">Release Process</a></li> + </ul> + </li> + </ul> + <ul class="navbar-nav nav navbar-right"> + <li class="dropdown"> + <a class="dropdown-toggle" data-toggle="dropdown" href="#">Apache Software Foundation<span class="caret"></span></a> + <ul class="dropdown-menu"> + <li><a href="https://www.apache.org">Apache Homepage</a></li> + <li><a href="https://www.apache.org/licenses/LICENSE-2.0">License</a></li> + <li><a href="https://www.apache.org/foundation/sponsorship">Sponsorship</i></a></li> + <li><a href="https://www.apache.org/security">Security</a></li> + <li><a href="https://www.apache.org/foundation/thanks">Thanks</a></li> + <li><a href="https://www.apache.org/foundation/policies/conduct">Code of Conduct</a></li> + </ul> + </li> + </ul> + </div> + </div> + </div> + <div class="container"> + <div class="row"> + <div class="col-sm-12"> + + + +<div id="tour-header"> + <h2><a href="/tour/">Fluo Tour</a>: Scanning Code</h2> + <p class="text-muted">Tour page 14 of 26</p> +</div> +<div id="tour-content"> + <div class="language-java highlighter-rouge"><pre class="highlight"><code> <span class="kd">private</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">excercise</span><span class="o">(</span><span class="n">MiniFluo</span> <span class="n">mini</span><span class="o">,</span> <span class="n">FluoClient</span> <span class="n">client</span><span class="o">)</span> <span class="o">{</span> + <span class="n">Column</span> <span class="n">fName</span> <span class="o">=</span> <span class="k">new</span> <span class="n">Column</span><span class="o">(</span><span class="s">"name"</span><span class="o">,</span> <span class="s">"first"</span><span class="o">);</span> + <span class="n">Column</span> <span class="n">lName</span> <span class="o">=</span> <span class="k">new</span> <span class="n">Column</span><span class="o">(</span><span class="s">"name"</span><span class="o">,</span> <span class="s">"last"</span><span class="o">);</span> + <span class="n">Column</span> <span class="n">bravery</span> <span class="o">=</span> <span class="k">new</span> <span class="n">Column</span><span class="o">(</span><span class="s">"attr"</span><span class="o">,</span><span class="s">"bravery"</span><span class="o">);</span> + + <span class="k">try</span><span class="o">(</span><span class="n">Transaction</span> <span class="n">tx1</span> <span class="o">=</span> <span class="n">client</span><span class="o">.</span><span class="na">newTransaction</span><span class="o">())</span> <span class="o">{</span> + <span class="n">tx1</span><span class="o">.</span><span class="na">set</span><span class="o">(</span><span class="s">"kerbalnaut0001"</span><span class="o">,</span> <span class="n">fName</span><span class="o">,</span> <span class="s">"Jebediah"</span><span class="o">);</span> + <span class="n">tx1</span><span class="o">.</span><span class="na">set</span><span class="o">(</span><span class="s">"kerbalnaut0001"</span><span class="o">,</span> <span class="n">lName</span><span class="o">,</span> <span class="s">"Kerman"</span><span class="o">);</span> + <span class="n">tx1</span><span class="o">.</span><span class="na">set</span><span class="o">(</span><span class="s">"kerbalnaut0001"</span><span class="o">,</span> <span class="n">bravery</span><span class="o">,</span> <span class="s">"5"</span><span class="o">);</span> + + <span class="n">tx1</span><span class="o">.</span><span class="na">set</span><span class="o">(</span><span class="s">"kerbalnaut0002"</span><span class="o">,</span> <span class="n">fName</span><span class="o">,</span> <span class="s">"Bill"</span><span class="o">);</span> + <span class="n">tx1</span><span class="o">.</span><span class="na">set</span><span class="o">(</span><span class="s">"kerbalnaut0002"</span><span class="o">,</span> <span class="n">lName</span><span class="o">,</span> <span class="s">"Kerman"</span><span class="o">);</span> + <span class="n">tx1</span><span class="o">.</span><span class="na">set</span><span class="o">(</span><span class="s">"kerbalnaut0002"</span><span class="o">,</span> <span class="n">bravery</span><span class="o">,</span> <span class="s">"2"</span><span class="o">);</span> + + <span class="n">tx1</span><span class="o">.</span><span class="na">set</span><span class="o">(</span><span class="s">"kerbalnaut0003"</span><span class="o">,</span> <span class="n">fName</span><span class="o">,</span> <span class="s">"Bob"</span><span class="o">);</span> + <span class="n">tx1</span><span class="o">.</span><span class="na">set</span><span class="o">(</span><span class="s">"kerbalnaut0003"</span><span class="o">,</span> <span class="n">lName</span><span class="o">,</span> <span class="s">"Kerman"</span><span class="o">);</span> + <span class="n">tx1</span><span class="o">.</span><span class="na">set</span><span class="o">(</span><span class="s">"kerbalnaut0003"</span><span class="o">,</span> <span class="n">bravery</span><span class="o">,</span> <span class="s">"1"</span><span class="o">);</span> + + <span class="n">tx1</span><span class="o">.</span><span class="na">set</span><span class="o">(</span><span class="s">"bravery5"</span><span class="o">,</span> <span class="k">new</span> <span class="n">Column</span><span class="o">(</span><span class="s">"id"</span><span class="o">,</span> <span class="s">"kerbalnaut0001"</span><span class="o">),</span> <span class="s">"5"</span><span class="o">);</span> + <span class="n">tx1</span><span class="o">.</span><span class="na">set</span><span class="o">(</span><span class="s">"bravery2"</span><span class="o">,</span> <span class="k">new</span> <span class="n">Column</span><span class="o">(</span><span class="s">"id"</span><span class="o">,</span> <span class="s">"kerbalnaut0002"</span><span class="o">),</span> <span class="s">"2"</span><span class="o">);</span> + <span class="n">tx1</span><span class="o">.</span><span class="na">set</span><span class="o">(</span><span class="s">"bravery1"</span><span class="o">,</span> <span class="k">new</span> <span class="n">Column</span><span class="o">(</span><span class="s">"id"</span><span class="o">,</span> <span class="s">"kerbalnaut0003"</span><span class="o">),</span> <span class="s">"1"</span><span class="o">);</span> + + <span class="n">tx1</span><span class="o">.</span><span class="na">commit</span><span class="o">();</span> + <span class="o">}</span> + + <span class="k">try</span><span class="o">(</span><span class="n">Snapshot</span> <span class="n">s1</span> <span class="o">=</span> <span class="n">client</span><span class="o">.</span><span class="na">newSnapshot</span><span class="o">())</span> <span class="o">{</span> + <span class="c1">//scan over an entire row</span> + <span class="n">CellScanner</span> <span class="n">cellScanner</span> <span class="o">=</span> <span class="n">s1</span><span class="o">.</span><span class="na">scanner</span><span class="o">().</span><span class="na">over</span><span class="o">(</span><span class="n">Span</span><span class="o">.</span><span class="na">exact</span><span class="o">(</span><span class="s">"kerbalnaut0002"</span><span class="o">)).</span><span class="na">build</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">println</span><span class="o">(</span><span class="s">"Scan 1 :"</span><span class="o">);</span> + <span class="k">for</span> <span class="o">(</span><span class="n">RowColumnValue</span> <span class="n">rcv</span> <span class="o">:</span> <span class="n">cellScanner</span><span class="o">)</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">println</span><span class="o">(</span><span class="s">"\t"</span><span class="o">+</span><span class="n">rcv</span><span class="o">);</span> + <span class="o">}</span> + + <span class="c1">//scan over a row and column family</span> + <span class="n">cellScanner</span> <span class="o">=</span> <span class="n">s1</span><span class="o">.</span><span class="na">scanner</span><span class="o">().</span><span class="na">over</span><span class="o">(</span><span class="n">Span</span><span class="o">.</span><span class="na">exact</span><span class="o">(</span><span class="s">"kerbalnaut0002"</span><span class="o">,</span> <span class="k">new</span> <span class="n">Column</span><span class="o">(</span><span class="s">"name"</span><span class="o">))).</span><span class="na">build</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">println</span><span class="o">(</span><span class="s">"\nScan 2 :"</span><span class="o">);</span> + <span class="k">for</span> <span class="o">(</span><span class="n">RowColumnValue</span> <span class="n">rcv</span> <span class="o">:</span> <span class="n">cellScanner</span><span class="o">)</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">println</span><span class="o">(</span><span class="s">"\t"</span><span class="o">+</span><span class="n">rcv</span><span class="o">);</span> + <span class="o">}</span> + + <span class="c1">//scan over two columns</span> + <span class="n">cellScanner</span> <span class="o">=</span> <span class="n">s1</span><span class="o">.</span><span class="na">scanner</span><span class="o">().</span><span class="na">over</span><span class="o">(</span><span class="n">Span</span><span class="o">.</span><span class="na">prefix</span><span class="o">(</span><span class="s">"kerbalnaut"</span><span class="o">)).</span><span class="na">fetch</span><span class="o">(</span><span class="n">fName</span><span class="o">,</span> <span class="n">bravery</span><span class="o">).</span><span class="na">build</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">println</span><span class="o">(</span><span class="s">"\nScan 3 :"</span><span class="o">);</span> + <span class="c1">//use Java lamda's to print instead of foreach loop</span> + <span class="n">cellScanner</span><span class="o">.</span><span class="na">forEach</span><span class="o">(</span><span class="n">rcv</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">println</span><span class="o">(</span><span class="s">"\t"</span><span class="o">+</span><span class="n">rcv</span><span class="o">));</span> + <span class="o">}</span> + <span class="o">}</span> +</code></pre> +</div> + +<p>The code above prints :</p> + +<div class="highlighter-rouge"><pre class="highlight"><code>Starting MiniFluo ... started. +Scan 1 : + kerbalnaut0002 attr bravery 2 + kerbalnaut0002 name first Bill + kerbalnaut0002 name last Kerman + +Scan 2 : + kerbalnaut0002 name first Bill + kerbalnaut0002 name last Kerman + +Scan 3 : + kerbalnaut0001 attr bravery 5 + kerbalnaut0001 name first Jebediah + kerbalnaut0002 attr bravery 2 + kerbalnaut0002 name first Bill + kerbalnaut0003 attr bravery 1 + kerbalnaut0003 name first Bob +</code></pre> +</div> + +</div> + +<script> +document.body.onkeyup = function(e){ + +if (e.keyCode == '37') { window.location = '/tour/scanning/'; } + + + +if (e.keyCode == '39') { window.location = '/tour/multi-get/'; } + +}; +</script> + +<div class="text-center"> + + <h2> + + <a href="/tour/scanning/"><</a> + + + 14 / 26 + + <a href="/tour/multi-get/">></a> + + </h2> +</div> + + </div> + </div> + <hr> + <div class="row footer"> + <div class="col-sm-12 text-center"> + <div class="center-block"> + <a href="https://apache.org"><img src="/resources/feather.png" alt="Apache"></a> + Copyright © 2016 The Apache Software Foundation. Licensed under the <a href="https://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a> + </div> + </div> + </div> + </div> + <script src="/javascripts/jquery.min.js"></script> + <script src="/javascripts/bootstrap.min.js"></script> + <!-- Place your <script> tags here. --> + +<!-- Google Analytics --> +<script> + (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){ + (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o), + m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m) + })(window,document,'script','https://www.google-analytics.com/analytics.js','ga'); + + ga('create', 'UA-55360307-1', 'auto'); + ga('send', 'pageview'); + +</script> + + </body> +</html>