Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Initial commit

  • Loading branch information...
commit 894315351253f6d8aac95a2e465c2f0540fdfb1d 0 parents
Joseph Wayne Norton authored
2  .gitignore
@@ -0,0 +1,2 @@
+.test/
+ebin/
21 LICENSE
@@ -0,0 +1,21 @@
+The MIT License
+
+Copyright (C) 2011-2012 by Joseph Wayne Norton <norton@alum.mit.edu>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
677 README.md
@@ -0,0 +1,677 @@
+
+
+#GEN_ETS - GEN(eric) Erlang Term Storage#
+
+
+Copyright (c) 2011-2012 by Joseph Wayne Norton
+
+__Authors:__ Joseph Wayne Norton ([`norton@alum.mit.edu`](mailto:norton@alum.mit.edu)).<p>GEN_ETS is an generic wrapper for Erlang Term Storage with a callback
+interface for a backend implementation.</p>
+<p>For testing purposes, GEN_ETS supports a default backend
+implementation:</p>
+<ul>
+<li>
+<p>
+<tt>ets</tt> Erlang ETS backend
+</p>
+</li>
+</ul>
+<p>GEN_ETS is not intended to be an exact clone of ETS. The currently
+supported ETS APIs are:</p>
+<ul>
+<li>
+<p>
+<tt>all/0</tt>
+</p>
+</li>
+<li>
+<p>
+<tt>delete/1</tt>
+</p>
+</li>
+<li>
+<p>
+<tt>delete/2</tt>
+</p>
+</li>
+<li>
+<p>
+<tt>delete_all_objects/1</tt>
+</p>
+</li>
+<li>
+<p>
+<tt>first/1</tt>
+</p>
+</li>
+<li>
+<p>
+<tt>foldl/3</tt>
+</p>
+</li>
+<li>
+<p>
+<tt>foldr/3</tt>
+</p>
+</li>
+<li>
+<p>
+<tt>info/1</tt> <em>only a subset of items</em>
+</p>
+</li>
+<li>
+<p>
+<tt>info/2</tt> <em>only a subset of items</em>
+</p>
+</li>
+<li>
+<p>
+<tt>insert/2</tt>
+</p>
+</li>
+<li>
+<p>
+<tt>insert_new/2</tt>
+</p>
+</li>
+<li>
+<p>
+<tt>last/1</tt>
+</p>
+</li>
+<li>
+<p>
+<tt>lookup/2</tt>
+</p>
+</li>
+<li>
+<p>
+<tt>lookup_element/3</tt>
+</p>
+</li>
+<li>
+<p>
+<tt>match/1</tt>
+</p>
+</li>
+<li>
+<p>
+<tt>match/2</tt>
+</p>
+</li>
+<li>
+<p>
+<tt>match/3</tt>
+</p>
+</li>
+<li>
+<p>
+<tt>match_delete/2</tt>
+</p>
+</li>
+<li>
+<p>
+<tt>match_object/1</tt>
+</p>
+</li>
+<li>
+<p>
+<tt>match_object/2</tt>
+</p>
+</li>
+<li>
+<p>
+<tt>match_object/3</tt>
+</p>
+</li>
+<li>
+<p>
+<tt>member/2</tt>
+</p>
+</li>
+<li>
+<p>
+<tt>new/2</tt>
+</p>
+</li>
+<li>
+<p>
+<tt>next/2</tt>
+</p>
+</li>
+<li>
+<p>
+<tt>prev/2</tt>
+</p>
+</li>
+<li>
+<p>
+<tt>select/1</tt>
+</p>
+</li>
+<li>
+<p>
+<tt>select/2</tt>
+</p>
+</li>
+<li>
+<p>
+<tt>select/3</tt>
+</p>
+</li>
+<li>
+<p>
+<tt>select_count/2</tt>
+</p>
+</li>
+<li>
+<p>
+<tt>select_delete/2</tt>
+</p>
+</li>
+<li>
+<p>
+<tt>select_reverse/1</tt>
+</p>
+</li>
+<li>
+<p>
+<tt>select_reverse/2</tt>
+</p>
+</li>
+<li>
+<p>
+<tt>select_reverse/3</tt>
+</p>
+</li>
+<li>
+<p>
+<tt>tab2list/1</tt>
+</p>
+</li>
+</ul>
+<p><em>This repository is experimental in nature - use at your own risk and
+please contribute if you find GEN_ETS useful.</em></p>
+
+<h2 id="_quick_start_recipe">Quick Start Recipe</h2>
+
+<p>To download and build the gen_ets application in one shot, please follow
+this recipe:</p>
+
+
+<pre><tt>$ mkdir working-directory-name
+$ cd working-directory-name
+$ git clone https://github.com/norton/gen_ets.git gen_ets
+$ cd gen_ets
+$ ./rebar get-deps
+$ ./rebar clean
+$ ./rebar compile</tt></pre>
+
+<p><em>OR</em> if QuickCheck is available then follow the this recipe:</p>
+
+
+<pre><tt>$ mkdir working-directory-name
+$ cd working-directory-name
+$ git clone https://github.com/norton/gen_ets.git gen_ets
+$ cd gen_ets
+$ ./rebar get-deps
+$ ./rebar clean
+$ ./rebar compile -D QC -D QC_EQC
+$ ./rebar test-compile -D QC -D QC_EQC
+$ (cd .test; erl -smp +A 5 -pz ../../qc/ebin)
+
+1> qc_statem_gen_ets:qc_run(500, []).
+ :
+ :
+OK, passed 500 tests
+
+100.0% {1,attempts}
+
+7.11% {delete,ok}
+6.78% {new,ok}
+3.91% {insert_new,ok}
+3.83% {select_reverse31,ok}
+3.76% {select31,ok}
+3.69% {tab2list,ok}
+3.69% {match31,ok}
+3.69% {first,ok}
+3.67% {delete_all_objects,ok}
+3.66% {foldl,ok}
+3.63% {select,ok}
+3.63% {member,ok}
+3.61% {select_count,ok}
+3.61% {last,ok}
+3.61% {foldr,ok}
+3.57% {insert,ok}
+3.50% {match_object31,ok}
+3.49% {match_delete,ok}
+3.44% {lookup,ok}
+3.42% {select_delete,ok}
+3.36% {match_object,ok}
+3.34% {select_reverse,ok}
+3.19% {match,ok}
+2.92% {lookup_element,{error,badarg}}
+2.17% {prev,ok}
+1.88% {next,ok}
+1.57% {next,{error,badarg}}
+1.56% {prev,{error,badarg}}
+0.72% {lookup_element,ok}
+true</tt></pre>
+
+<p>For an alternative recipe with other "features" albeit more complex,
+please read further.</p>
+
+
+
+<h2 id="_documentation">Documentation</h2>
+
+
+<h3 id="_where_should_i_start">Where should I start?</h3>
+<p>This README is the only bit of documentation right now.</p>
+<p>The QC (a.k.a. QuickCheck, PropEr, etc.) tests underneath the
+"tests/qc" directory should be helpful for understanding the
+specification and behavior of ETS and GEN_ETS. NIF-based
+implementations.</p>
+
+
+<h3 id="_what_is_ets_and_dets">What is ETS and DETS?</h3>
+<p>ETS and DETS are Erlang/OTP's standard library modules for Erlang
+term storage. ETS is a memory-based implementation. DETS is a
+disk-based implementation.</p>
+<p>See <a href="http://www.erlang.org/doc/man/ets.html">http://www.erlang.org/doc/man/ets.html</a> and
+<a href="http://www.erlang.org/doc/man/dets.html">http://www.erlang.org/doc/man/dets.html</a> for further details.</p>
+
+
+
+
+<h2 id="_to_download">To download</h2>
+
+<ol class="arabic">
+<li>
+<p>
+Configure your e-mail and name for Git
+</p>
+
+
+<pre><tt>$ git config \--global user.email "you@example.com"
+$ git config \--global user.name "Your Name"</tt></pre>
+
+</li>
+<li>
+<p>
+Install Repo
+</p>
+
+
+<pre><tt>$ mkdir -p ~/bin
+$ wget -O - https://dl-ssl.google.com/dl/googlesource/git-repo/repo > ~/bin/repo
+$ chmod a+x ~/bin/repo</tt></pre>
+
+</li>
+<li>
+<p>
+Create working directory
+</p>
+
+
+<pre><tt>$ mkdir working-directory-name
+$ cd working-directory-name
+$ repo init -u https://github.com/norton/manifests.git -m gen_ets-default.xml</tt></pre>
+
+
+<table><tr>
+<td class="icon">
+Note
+</td>
+<td class="content">Your "Git" identity is needed during the init step. Please
+enter the name and email of your GitHub account if you have one. Team
+members having read-write access are recommended to use "repo init -u
+<a href="mailto:git@github.com">git@github.com</a>:norton/manifests.git -m gen_ets-default-rw.xml".</td>
+</tr></table>
+
+
+<table><tr>
+<td class="icon">
+Tip
+</td>
+<td class="content">If you want to checkout the latest development version, please
+append " -b dev" to the repo init command.</td>
+</tr></table>
+
+</li>
+<li>
+<p>
+Download Git repositories
+</p>
+
+
+<pre><tt>$ cd working-directory-name
+$ repo sync</tt></pre>
+
+</li>
+</ol>
+<p>For futher information and help for related tools, please refer to the
+following links:</p>
+<ul>
+<li>
+<p>
+Erlang - <a href="http://www.erlang.org/">http://www.erlang.org/</a>
+</p>
+<ul>
+<li>
+<p>
+<strong>R14 or newer, R15B02 has been tested recently</strong>
+</p>
+</li>
+</ul>
+</li>
+<li>
+<p>
+Git - <a href="http://git-scm.com/">http://git-scm.com/</a>
+</p>
+<ul>
+<li>
+<p>
+<strong>Git 1.5.4 or newer, Git 1.7.12 has been tested recently</strong>
+</p>
+</li>
+<li>
+<p>
+<em>required for Repo and GitHub</em>
+</p>
+</li>
+</ul>
+</li>
+<li>
+<p>
+GitHub - <a href="https://github.com">https://github.com</a>
+</p>
+</li>
+<li>
+<p>
+Python - <a href="http://www.python.org">http://www.python.org</a>
+</p>
+<ul>
+<li>
+<p>
+<strong>Python 2.4 or newer, Python 2.7.2 has been tested recently
+ (CAUTION: Python 3.x might be too new)</strong>
+</p>
+</li>
+<li>
+<p>
+<em>required for Repo</em>
+</p>
+</li>
+</ul>
+</li>
+<li>
+<p>
+Rebar - <a href="https://github.com/basho/rebar/wiki">https://github.com/basho/rebar/wiki</a>
+</p>
+</li>
+<li>
+<p>
+Repo - <a href="http://source.android.com/source/git-repo.md">http://source.android.com/source/git-repo.html</a>
+</p>
+</li>
+</ul>
+
+
+
+<h2 id="_to_build_basic_recipe">To build - basic recipe</h2>
+
+<ol class="arabic">
+<li>
+<p>
+Get and install an erlang system <a href="http://www.erlang.org">http://www.erlang.org</a>
+</p>
+</li>
+<li>
+<p>
+Build
+</p>
+
+
+<pre><tt>$ cd working-directory-name
+$ make compile</tt></pre>
+
+</li>
+</ol>
+
+
+
+<h2 id="_to_build_optional_features">To build - optional features</h2>
+
+<ol class="upperalpha">
+<li>
+<p>
+Dialyzer Testing <em>basic recipe</em>
+</p>
+<ol class="arabic">
+<li>
+<p>
+Build Dialyzer's PLT <em>(required once)</em>
+</p>
+
+
+<pre><tt>$ cd working-directory-name
+$ make build-plt</tt></pre>
+
+
+<table><tr>
+<td class="icon">
+Tip
+</td>
+<td class="content">Check Makefile and dialyzer's documentation for further
+information.</td>
+</tr></table>
+
+</li>
+<li>
+<p>
+Dialyze with specs
+</p>
+
+
+<pre><tt>$ cd working-directory-name
+$ make dialyze</tt></pre>
+
+
+<table><tr>
+<td class="icon">
+Caution
+</td>
+<td class="content">If you manually run dialyzer with the "-r" option, execute
+"make clean compile" first to avoid finding duplicate beam files
+underneath rebar's .test directory. Check Makefile for further
+information.</td>
+</tr></table>
+
+</li>
+<li>
+<p>
+Dialyze without specs
+</p>
+
+
+<pre><tt>$ cd working-directory-name
+$ make dialyze-nospec</tt></pre>
+
+</li>
+</ol>
+</li>
+</ol>
+
+
+
+<h2 id="_to_test_quickcheck">To test - QuickCheck</h2>
+
+<ol class="arabic">
+<li>
+<p>
+Make sure QuickCheck is in your Erlang code path. One simple way
+ to accomplish this is by adding the code path to your <tt>~/.erlang</tt>
+ resource file.
+</p>
+
+
+<pre><tt>true = code:add_pathz(os:getenv("HOME")++"/.erlang.d/deps/quviq/eqc-X.Y.Z/ebin").</tt></pre>
+
+</li>
+<li>
+<p>
+Compile for QuickCheck
+</p>
+
+
+<pre><tt>$ cd working-directory-name
+$ make clean
+$ make eqc-compile</tt></pre>
+
+</li>
+<li>
+<p>
+Run 5,000 QuickCheck tests
+</p>
+
+
+<pre><tt>$ cd working-directory-name/deps/gen_ets/.test
+$ erl -smp +A 5 -pz -pz ../../qc/ebin
+
+1> qc_statem_gen_ets:qc_run(5000).
+....
+OK, passed 5000 tests
+
+100.0% {1,attempts}
+
+7.11% {delete,ok}
+6.78% {new,ok}
+3.91% {insert_new,ok}
+3.83% {select_reverse31,ok}
+3.76% {select31,ok}
+3.69% {tab2list,ok}
+3.69% {match31,ok}
+3.69% {first,ok}
+3.67% {delete_all_objects,ok}
+3.66% {foldl,ok}
+3.63% {select,ok}
+3.63% {member,ok}
+3.61% {select_count,ok}
+3.61% {last,ok}
+3.61% {foldr,ok}
+3.57% {insert,ok}
+3.50% {match_object31,ok}
+3.49% {match_delete,ok}
+3.44% {lookup,ok}
+3.42% {select_delete,ok}
+3.36% {match_object,ok}
+3.34% {select_reverse,ok}
+3.19% {match,ok}
+2.92% {lookup_element,{error,badarg}}
+2.17% {prev,ok}
+1.88% {next,ok}
+1.57% {next,{error,badarg}}
+1.56% {prev,{error,badarg}}
+0.72% {lookup_element,ok}
+true
+.......</tt></pre>
+
+
+<table><tr>
+<td class="icon">
+Tip
+</td>
+<td class="content">For testing LevelDB directly using the C bindings, try<tt>qc_statemc_gen_ets:qc_run(5000)</tt>.</td>
+</tr></table>
+
+</li>
+</ol>
+
+
+
+<h2 id="_to_test_proper">To test - PropEr</h2>
+
+<ol class="arabic">
+<li>
+<p>
+Make sure PropEr is in your Erlang code path. One simple way to
+ accomplish this is by adding the code path to your <tt>~/.erlang</tt>
+ resource file.
+</p>
+
+
+<pre><tt>true = code:add_pathz(os:getenv("HOME")++"/.erlang.d/deps/proper/ebin").</tt></pre>
+
+</li>
+<li>
+<p>
+Compile for PropEr
+</p>
+
+
+<pre><tt>$ cd working-directory-name
+$ make clean
+$ make proper-compile</tt></pre>
+
+</li>
+<li>
+<p>
+Run 5,000 PropEr tests
+</p>
+
+
+<pre><tt>$ cd working-directory-name/deps/gen_ets/.test
+$ erl -smp +A 5 -pz -pz ../../qc/ebin
+
+1> qc_statem_gen_ets:qc_run(5000).
+....
+OK: Passed 5000 test(s).
+
+11% {new,ok}
+8% {delete,ok}
+4% {member,ok}
+4% {select,ok}
+4% {select_count,ok}
+4% {select_reverse,ok}
+4% {lookup,ok}
+4% {match_object,ok}
+4% {tab2list,ok}
+4% {last,ok}
+4% {match,ok}
+4% {foldl,ok}
+4% {match_delete,ok}
+3% {prev,ok}
+3% {select31,ok}
+3% {select_delete,ok}
+3% {foldr,ok}
+3% {insert,ok}
+3% {first,ok}
+3% {next,ok}
+3% {lookup_element,{error,badarg}}
+1% {insert_new,ok}
+0% {prev,{error,badarg}}
+0% {lookup_element,ok}
+0% {next,{error,badarg}}
+true
+.......</tt></pre>
+
+</li>
+</ol>
+
+
+
+<h2 id="_roadmap">Roadmap</h2>
+
+<p><em>TODO</em></p>
+
+
+
+
+##Modules##
+
+
+<table width="100%" border="0" summary="list of modules">
+<tr><td><a href="https://github.com/norton/gen_ets/blob/master/doc/gen_ets.md" class="module">gen_ets</a></td></tr>
+<tr><td><a href="https://github.com/norton/gen_ets/blob/master/doc/gen_ets_impl_ets.md" class="module">gen_ets_impl_ets</a></td></tr></table>
+
3  THANKS
@@ -0,0 +1,3 @@
+The following people have contributed to gen_ets:
+
+Joseph Wayne Norton
677 doc/README.md
@@ -0,0 +1,677 @@
+
+
+#GEN_ETS - GEN(eric) Erlang Term Storage#
+
+
+Copyright (c) 2011-2012 by Joseph Wayne Norton
+
+__Authors:__ Joseph Wayne Norton ([`norton@alum.mit.edu`](mailto:norton@alum.mit.edu)).<p>GEN_ETS is an generic wrapper for Erlang Term Storage with a callback
+interface for a backend implementation.</p>
+<p>For testing purposes, GEN_ETS supports a default backend
+implementation:</p>
+<ul>
+<li>
+<p>
+<tt>ets</tt> Erlang ETS backend
+</p>
+</li>
+</ul>
+<p>GEN_ETS is not intended to be an exact clone of ETS. The currently
+supported ETS APIs are:</p>
+<ul>
+<li>
+<p>
+<tt>all/0</tt>
+</p>
+</li>
+<li>
+<p>
+<tt>delete/1</tt>
+</p>
+</li>
+<li>
+<p>
+<tt>delete/2</tt>
+</p>
+</li>
+<li>
+<p>
+<tt>delete_all_objects/1</tt>
+</p>
+</li>
+<li>
+<p>
+<tt>first/1</tt>
+</p>
+</li>
+<li>
+<p>
+<tt>foldl/3</tt>
+</p>
+</li>
+<li>
+<p>
+<tt>foldr/3</tt>
+</p>
+</li>
+<li>
+<p>
+<tt>info/1</tt> <em>only a subset of items</em>
+</p>
+</li>
+<li>
+<p>
+<tt>info/2</tt> <em>only a subset of items</em>
+</p>
+</li>
+<li>
+<p>
+<tt>insert/2</tt>
+</p>
+</li>
+<li>
+<p>
+<tt>insert_new/2</tt>
+</p>
+</li>
+<li>
+<p>
+<tt>last/1</tt>
+</p>
+</li>
+<li>
+<p>
+<tt>lookup/2</tt>
+</p>
+</li>
+<li>
+<p>
+<tt>lookup_element/3</tt>
+</p>
+</li>
+<li>
+<p>
+<tt>match/1</tt>
+</p>
+</li>
+<li>
+<p>
+<tt>match/2</tt>
+</p>
+</li>
+<li>
+<p>
+<tt>match/3</tt>
+</p>
+</li>
+<li>
+<p>
+<tt>match_delete/2</tt>
+</p>
+</li>
+<li>
+<p>
+<tt>match_object/1</tt>
+</p>
+</li>
+<li>
+<p>
+<tt>match_object/2</tt>
+</p>
+</li>
+<li>
+<p>
+<tt>match_object/3</tt>
+</p>
+</li>
+<li>
+<p>
+<tt>member/2</tt>
+</p>
+</li>
+<li>
+<p>
+<tt>new/2</tt>
+</p>
+</li>
+<li>
+<p>
+<tt>next/2</tt>
+</p>
+</li>
+<li>
+<p>
+<tt>prev/2</tt>
+</p>
+</li>
+<li>
+<p>
+<tt>select/1</tt>
+</p>
+</li>
+<li>
+<p>
+<tt>select/2</tt>
+</p>
+</li>
+<li>
+<p>
+<tt>select/3</tt>
+</p>
+</li>
+<li>
+<p>
+<tt>select_count/2</tt>
+</p>
+</li>
+<li>
+<p>
+<tt>select_delete/2</tt>
+</p>
+</li>
+<li>
+<p>
+<tt>select_reverse/1</tt>
+</p>
+</li>
+<li>
+<p>
+<tt>select_reverse/2</tt>
+</p>
+</li>
+<li>
+<p>
+<tt>select_reverse/3</tt>
+</p>
+</li>
+<li>
+<p>
+<tt>tab2list/1</tt>
+</p>
+</li>
+</ul>
+<p><em>This repository is experimental in nature - use at your own risk and
+please contribute if you find GEN_ETS useful.</em></p>
+
+<h2 id="_quick_start_recipe">Quick Start Recipe</h2>
+
+<p>To download and build the gen_ets application in one shot, please follow
+this recipe:</p>
+
+
+<pre><tt>$ mkdir working-directory-name
+$ cd working-directory-name
+$ git clone https://github.com/norton/gen_ets.git gen_ets
+$ cd gen_ets
+$ ./rebar get-deps
+$ ./rebar clean
+$ ./rebar compile</tt></pre>
+
+<p><em>OR</em> if QuickCheck is available then follow the this recipe:</p>
+
+
+<pre><tt>$ mkdir working-directory-name
+$ cd working-directory-name
+$ git clone https://github.com/norton/gen_ets.git gen_ets
+$ cd gen_ets
+$ ./rebar get-deps
+$ ./rebar clean
+$ ./rebar compile -D QC -D QC_EQC
+$ ./rebar test-compile -D QC -D QC_EQC
+$ (cd .test; erl -smp +A 5 -pz ../../qc/ebin)
+
+1> qc_statem_gen_ets:qc_run(500, []).
+ :
+ :
+OK, passed 500 tests
+
+100.0% {1,attempts}
+
+7.11% {delete,ok}
+6.78% {new,ok}
+3.91% {insert_new,ok}
+3.83% {select_reverse31,ok}
+3.76% {select31,ok}
+3.69% {tab2list,ok}
+3.69% {match31,ok}
+3.69% {first,ok}
+3.67% {delete_all_objects,ok}
+3.66% {foldl,ok}
+3.63% {select,ok}
+3.63% {member,ok}
+3.61% {select_count,ok}
+3.61% {last,ok}
+3.61% {foldr,ok}
+3.57% {insert,ok}
+3.50% {match_object31,ok}
+3.49% {match_delete,ok}
+3.44% {lookup,ok}
+3.42% {select_delete,ok}
+3.36% {match_object,ok}
+3.34% {select_reverse,ok}
+3.19% {match,ok}
+2.92% {lookup_element,{error,badarg}}
+2.17% {prev,ok}
+1.88% {next,ok}
+1.57% {next,{error,badarg}}
+1.56% {prev,{error,badarg}}
+0.72% {lookup_element,ok}
+true</tt></pre>
+
+<p>For an alternative recipe with other "features" albeit more complex,
+please read further.</p>
+
+
+
+<h2 id="_documentation">Documentation</h2>
+
+
+<h3 id="_where_should_i_start">Where should I start?</h3>
+<p>This README is the only bit of documentation right now.</p>
+<p>The QC (a.k.a. QuickCheck, PropEr, etc.) tests underneath the
+"tests/qc" directory should be helpful for understanding the
+specification and behavior of ETS and GEN_ETS. NIF-based
+implementations.</p>
+
+
+<h3 id="_what_is_ets_and_dets">What is ETS and DETS?</h3>
+<p>ETS and DETS are Erlang/OTP's standard library modules for Erlang
+term storage. ETS is a memory-based implementation. DETS is a
+disk-based implementation.</p>
+<p>See <a href="http://www.erlang.org/doc/man/ets.html">http://www.erlang.org/doc/man/ets.html</a> and
+<a href="http://www.erlang.org/doc/man/dets.html">http://www.erlang.org/doc/man/dets.html</a> for further details.</p>
+
+
+
+
+<h2 id="_to_download">To download</h2>
+
+<ol class="arabic">
+<li>
+<p>
+Configure your e-mail and name for Git
+</p>
+
+
+<pre><tt>$ git config \--global user.email "you@example.com"
+$ git config \--global user.name "Your Name"</tt></pre>
+
+</li>
+<li>
+<p>
+Install Repo
+</p>
+
+
+<pre><tt>$ mkdir -p ~/bin
+$ wget -O - https://dl-ssl.google.com/dl/googlesource/git-repo/repo > ~/bin/repo
+$ chmod a+x ~/bin/repo</tt></pre>
+
+</li>
+<li>
+<p>
+Create working directory
+</p>
+
+
+<pre><tt>$ mkdir working-directory-name
+$ cd working-directory-name
+$ repo init -u https://github.com/norton/manifests.git -m gen_ets-default.xml</tt></pre>
+
+
+<table><tr>
+<td class="icon">
+Note
+</td>
+<td class="content">Your "Git" identity is needed during the init step. Please
+enter the name and email of your GitHub account if you have one. Team
+members having read-write access are recommended to use "repo init -u
+<a href="mailto:git@github.com">git@github.com</a>:norton/manifests.git -m gen_ets-default-rw.xml".</td>
+</tr></table>
+
+
+<table><tr>
+<td class="icon">
+Tip
+</td>
+<td class="content">If you want to checkout the latest development version, please
+append " -b dev" to the repo init command.</td>
+</tr></table>
+
+</li>
+<li>
+<p>
+Download Git repositories
+</p>
+
+
+<pre><tt>$ cd working-directory-name
+$ repo sync</tt></pre>
+
+</li>
+</ol>
+<p>For futher information and help for related tools, please refer to the
+following links:</p>
+<ul>
+<li>
+<p>
+Erlang - <a href="http://www.erlang.org/">http://www.erlang.org/</a>
+</p>
+<ul>
+<li>
+<p>
+<strong>R14 or newer, R15B02 has been tested recently</strong>
+</p>
+</li>
+</ul>
+</li>
+<li>
+<p>
+Git - <a href="http://git-scm.com/">http://git-scm.com/</a>
+</p>
+<ul>
+<li>
+<p>
+<strong>Git 1.5.4 or newer, Git 1.7.12 has been tested recently</strong>
+</p>
+</li>
+<li>
+<p>
+<em>required for Repo and GitHub</em>
+</p>
+</li>
+</ul>
+</li>
+<li>
+<p>
+GitHub - <a href="https://github.com">https://github.com</a>
+</p>
+</li>
+<li>
+<p>
+Python - <a href="http://www.python.org">http://www.python.org</a>
+</p>
+<ul>
+<li>
+<p>
+<strong>Python 2.4 or newer, Python 2.7.2 has been tested recently
+ (CAUTION: Python 3.x might be too new)</strong>
+</p>
+</li>
+<li>
+<p>
+<em>required for Repo</em>
+</p>
+</li>
+</ul>
+</li>
+<li>
+<p>
+Rebar - <a href="https://github.com/basho/rebar/wiki">https://github.com/basho/rebar/wiki</a>
+</p>
+</li>
+<li>
+<p>
+Repo - <a href="http://source.android.com/source/git-repo.md">http://source.android.com/source/git-repo.html</a>
+</p>
+</li>
+</ul>
+
+
+
+<h2 id="_to_build_basic_recipe">To build - basic recipe</h2>
+
+<ol class="arabic">
+<li>
+<p>
+Get and install an erlang system <a href="http://www.erlang.org">http://www.erlang.org</a>
+</p>
+</li>
+<li>
+<p>
+Build
+</p>
+
+
+<pre><tt>$ cd working-directory-name
+$ make compile</tt></pre>
+
+</li>
+</ol>
+
+
+
+<h2 id="_to_build_optional_features">To build - optional features</h2>
+
+<ol class="upperalpha">
+<li>
+<p>
+Dialyzer Testing <em>basic recipe</em>
+</p>
+<ol class="arabic">
+<li>
+<p>
+Build Dialyzer's PLT <em>(required once)</em>
+</p>
+
+
+<pre><tt>$ cd working-directory-name
+$ make build-plt</tt></pre>
+
+
+<table><tr>
+<td class="icon">
+Tip
+</td>
+<td class="content">Check Makefile and dialyzer's documentation for further
+information.</td>
+</tr></table>
+
+</li>
+<li>
+<p>
+Dialyze with specs
+</p>
+
+
+<pre><tt>$ cd working-directory-name
+$ make dialyze</tt></pre>
+
+
+<table><tr>
+<td class="icon">
+Caution
+</td>
+<td class="content">If you manually run dialyzer with the "-r" option, execute
+"make clean compile" first to avoid finding duplicate beam files
+underneath rebar's .test directory. Check Makefile for further
+information.</td>
+</tr></table>
+
+</li>
+<li>
+<p>
+Dialyze without specs
+</p>
+
+
+<pre><tt>$ cd working-directory-name
+$ make dialyze-nospec</tt></pre>
+
+</li>
+</ol>
+</li>
+</ol>
+
+
+
+<h2 id="_to_test_quickcheck">To test - QuickCheck</h2>
+
+<ol class="arabic">
+<li>
+<p>
+Make sure QuickCheck is in your Erlang code path. One simple way
+ to accomplish this is by adding the code path to your <tt>~/.erlang</tt>
+ resource file.
+</p>
+
+
+<pre><tt>true = code:add_pathz(os:getenv("HOME")++"/.erlang.d/deps/quviq/eqc-X.Y.Z/ebin").</tt></pre>
+
+</li>
+<li>
+<p>
+Compile for QuickCheck
+</p>
+
+
+<pre><tt>$ cd working-directory-name
+$ make clean
+$ make eqc-compile</tt></pre>
+
+</li>
+<li>
+<p>
+Run 5,000 QuickCheck tests
+</p>
+
+
+<pre><tt>$ cd working-directory-name/deps/gen_ets/.test
+$ erl -smp +A 5 -pz -pz ../../qc/ebin
+
+1> qc_statem_gen_ets:qc_run(5000).
+....
+OK, passed 5000 tests
+
+100.0% {1,attempts}
+
+7.11% {delete,ok}
+6.78% {new,ok}
+3.91% {insert_new,ok}
+3.83% {select_reverse31,ok}
+3.76% {select31,ok}
+3.69% {tab2list,ok}
+3.69% {match31,ok}
+3.69% {first,ok}
+3.67% {delete_all_objects,ok}
+3.66% {foldl,ok}
+3.63% {select,ok}
+3.63% {member,ok}
+3.61% {select_count,ok}
+3.61% {last,ok}
+3.61% {foldr,ok}
+3.57% {insert,ok}
+3.50% {match_object31,ok}
+3.49% {match_delete,ok}
+3.44% {lookup,ok}
+3.42% {select_delete,ok}
+3.36% {match_object,ok}
+3.34% {select_reverse,ok}
+3.19% {match,ok}
+2.92% {lookup_element,{error,badarg}}
+2.17% {prev,ok}
+1.88% {next,ok}
+1.57% {next,{error,badarg}}
+1.56% {prev,{error,badarg}}
+0.72% {lookup_element,ok}
+true
+.......</tt></pre>
+
+
+<table><tr>
+<td class="icon">
+Tip
+</td>
+<td class="content">For testing LevelDB directly using the C bindings, try<tt>qc_statemc_gen_ets:qc_run(5000)</tt>.</td>
+</tr></table>
+
+</li>
+</ol>
+
+
+
+<h2 id="_to_test_proper">To test - PropEr</h2>
+
+<ol class="arabic">
+<li>
+<p>
+Make sure PropEr is in your Erlang code path. One simple way to
+ accomplish this is by adding the code path to your <tt>~/.erlang</tt>
+ resource file.
+</p>
+
+
+<pre><tt>true = code:add_pathz(os:getenv("HOME")++"/.erlang.d/deps/proper/ebin").</tt></pre>
+
+</li>
+<li>
+<p>
+Compile for PropEr
+</p>
+
+
+<pre><tt>$ cd working-directory-name
+$ make clean
+$ make proper-compile</tt></pre>
+
+</li>
+<li>
+<p>
+Run 5,000 PropEr tests
+</p>
+
+
+<pre><tt>$ cd working-directory-name/deps/gen_ets/.test
+$ erl -smp +A 5 -pz -pz ../../qc/ebin
+
+1> qc_statem_gen_ets:qc_run(5000).
+....
+OK: Passed 5000 test(s).
+
+11% {new,ok}
+8% {delete,ok}
+4% {member,ok}
+4% {select,ok}
+4% {select_count,ok}
+4% {select_reverse,ok}
+4% {lookup,ok}
+4% {match_object,ok}
+4% {tab2list,ok}
+4% {last,ok}
+4% {match,ok}
+4% {foldl,ok}
+4% {match_delete,ok}
+3% {prev,ok}
+3% {select31,ok}
+3% {select_delete,ok}
+3% {foldr,ok}
+3% {insert,ok}
+3% {first,ok}
+3% {next,ok}
+3% {lookup_element,{error,badarg}}
+1% {insert_new,ok}
+0% {prev,{error,badarg}}
+0% {lookup_element,ok}
+0% {next,{error,badarg}}
+true
+.......</tt></pre>
+
+</li>
+</ol>
+
+
+
+<h2 id="_roadmap">Roadmap</h2>
+
+<p><em>TODO</em></p>
+
+
+
+
+##Modules##
+
+
+<table width="100%" border="0" summary="list of modules">
+<tr><td><a href="gen_ets.md" class="module">gen_ets</a></td></tr>
+<tr><td><a href="gen_ets_impl_ets.md" class="module">gen_ets_impl_ets</a></td></tr></table>
+
3  doc/edoc-info
@@ -0,0 +1,3 @@
+{application,gen_ets}.
+{packages,[]}.
+{modules,[gen_ets,gen_ets_impl_ets]}.
919 doc/gen_ets.md
@@ -0,0 +1,919 @@
+
+
+#Module gen_ets#
+* [Data Types](#types)
+* [Function Index](#index)
+* [Function Details](#functions)
+
+
+__This module defines the `gen_ets` behaviour.__
+<br></br>
+ Required callback functions: `open/2`, `destroy/2`, `repair/2`, `delete/1`, `delete/2`, `delete_all_objects/1`, `first/1`, `foldl/3`, `foldr/3`, `info/1`, `info/2`, `insert/2`, `insert_new/2`, `last/1`, `lookup/2`, `lookup_element/3`, `match/2`, `match/3`, `match/1`, `match_delete/2`, `match_object/2`, `match_object/3`, `match_object/1`, `member/2`, `next/2`, `prev/2`, `select/2`, `select/3`, `select/1`, `select_count/2`, `select_delete/2`, `select_reverse/2`, `select_reverse/3`, `select_reverse/1`, `tab2list/1`.
+<a name="types"></a>
+
+##Data Types##
+
+
+
+
+###<a name="type-cont">cont()</a>##
+
+
+
+__abstract datatype__: `cont()`
+
+
+
+###<a name="type-impl_opt">impl_opt()</a>##
+
+
+
+<pre>impl_opt() = term()</pre>
+
+
+
+###<a name="type-impl_opts">impl_opts()</a>##
+
+
+
+<pre>impl_opts() = [<a href="#type-impl_opt">impl_opt()</a>]</pre>
+
+
+
+###<a name="type-item">item()</a>##
+
+
+
+<pre>item() = owner | name | named_table | type | keypos | protection | compressed | async | memory | size</pre>
+
+
+
+###<a name="type-key">key()</a>##
+
+
+
+<pre>key() = term()</pre>
+
+
+
+###<a name="type-limit">limit()</a>##
+
+
+
+<pre>limit() = pos_integer()</pre>
+
+
+
+###<a name="type-match">match()</a>##
+
+
+
+<pre>match() = term()</pre>
+
+
+
+###<a name="type-match_pattern">match_pattern()</a>##
+
+
+
+<pre>match_pattern() = atom() | tuple()</pre>
+
+
+
+
+<pre><tt>ets:match_pattern() is not exported!</tt></pre>
+
+
+
+
+###<a name="type-match_spec">match_spec()</a>##
+
+
+
+<pre>match_spec() = <a href="ets.md#type-match_spec">ets:match_spec()</a></pre>
+
+
+
+###<a name="type-name">name()</a>##
+
+
+
+<pre>name() = term()</pre>
+
+
+
+###<a name="type-object">object()</a>##
+
+
+
+<pre>object() = tuple()</pre>
+
+
+
+###<a name="type-opt">opt()</a>##
+
+
+
+<pre>opt() = set | ordered_set | named_table | {keypos, pos_integer()} | public | protected | private | compressed | async</pre>
+
+
+
+###<a name="type-opts">opts()</a>##
+
+
+
+<pre>opts() = [<a href="#type-opt">opt()</a> | {impl, {module(), <a href="#type-impl_opts">impl_opts()</a>}}]</pre>
+
+
+
+###<a name="type-pos">pos()</a>##
+
+
+
+<pre>pos() = pos_integer()</pre>
+
+
+
+###<a name="type-tab">tab()</a>##
+
+
+
+<pre>tab() = <a href="#type-name">name()</a> | <a href="#type-tid">tid()</a></pre>
+
+
+
+###<a name="type-tid">tid()</a>##
+
+
+
+__abstract datatype__: `tid()`
+<a name="index"></a>
+
+##Function Index##
+
+
+<table width="100%" border="1" cellspacing="0" cellpadding="2" summary="function index"><tr><td valign="top"><a href="#all-0">all/0</a></td><td><p>Returns a list of all tables at the node.</p>.</td></tr><tr><td valign="top"><a href="#behaviour_info-1">behaviour_info/1</a></td><td></td></tr><tr><td valign="top"><a href="#delete-1">delete/1</a></td><td><p>Deletes the entire table <tt>Tab</tt>.</p>.</td></tr><tr><td valign="top"><a href="#delete-2">delete/2</a></td><td><p>Deletes all objects with the key <tt>Key</tt> from the table <tt>Tab</tt>.</p>.</td></tr><tr><td valign="top"><a href="#delete_all_objects-1">delete_all_objects/1</a></td><td><p>Delete all objects in the table <tt>Tab</tt>. The operation is
+guaranteed to be atomic and isolated. This function only applies
+to the <tt>ets</tt> implementation.</p>.</td></tr><tr><td valign="top"><a href="#destroy-2">destroy/2</a></td><td><p>Destroy the contents of the specified table.</p>.</td></tr><tr><td valign="top"><a href="#first-1">first/1</a></td><td><p>Returns the first key <tt>Key</tt> in the table <tt>Tab</tt>. If the table
+is empty, <tt><em>$end_of_table</em></tt> will be returned.</p>.</td></tr><tr><td valign="top"><a href="#foldl-3">foldl/3</a></td><td><p>Fold from left to right over the elements of the table.</p>.</td></tr><tr><td valign="top"><a href="#foldr-3">foldr/3</a></td><td><p>Fold from right to left over the elements of the table.</p>.</td></tr><tr><td valign="top"><a href="#info-1">info/1</a></td><td><p>Returns information about the table <tt>Tab</tt> as a list of <tt>{Item,
+ Value}</tt> tuples.</p>.</td></tr><tr><td valign="top"><a href="#info-2">info/2</a></td><td><p>Returns the information associated with <tt>Item</tt> for the table <tt>Tab</tt>.</p>
+
+
+<pre><tt>Valid +Item+ options are:</tt></pre>
+
+<ul>
+<li>
+<p>
+<tt>owner</tt>
+</p>
+</li>
+<li>
+<p>
+<tt>name</tt>
+</p>
+</li>
+<li>
+<p>
+<tt>named_table</tt> <em>only the ets implementation</em>
+</p>
+</li>
+<li>
+<p>
+<tt>type</tt>
+</p>
+</li>
+<li>
+<p>
+<tt>keypos</tt>
+</p>
+</li>
+<li>
+<p>
+<tt>protection</tt>
+</p>
+</li>
+<li>
+<p>
+<tt>compressed</tt>
+</p>
+</li>
+<li>
+<p>
+<tt>async</tt> <em>only the drv implementation</em>
+</p>
+</li>
+<li>
+<p>
+<tt>memory</tt> <em>only the ets implementation</em>
+</p>
+</li>
+<li>
+<p>
+<tt>size</tt> <em>only the ets implementation</em>
+</p>
+</li>
+</ul>.</td></tr><tr><td valign="top"><a href="#insert-2">insert/2</a></td><td><p>Inserts the object or all of the objects in the list
+<tt>ObjOrObjs</tt> into the table <tt>Tab</tt>.</p>.</td></tr><tr><td valign="top"><a href="#insert_new-2">insert_new/2</a></td><td><p>This function works exactly like <tt>insert/2</tt>, with the
+exception that instead of overwriting objects with the same key, it
+simply returns false. This function only applies to the <tt>ets</tt>
+implementation.</p>.</td></tr><tr><td valign="top"><a href="#last-1">last/1</a></td><td><p>Returns the last key <tt>Key</tt> in the table <tt>Tab</tt>. If the table
+is empty, <tt><em>$end_of_table</em></tt> will be returned.</p>.</td></tr><tr><td valign="top"><a href="#lookup-2">lookup/2</a></td><td><p>Returns a list of all objects with the key <tt>Key</tt> in the table
+<tt>Tab</tt>.</p>.</td></tr><tr><td valign="top"><a href="#lookup_element-3">lookup_element/3</a></td><td><p>Returns the <tt>Pos</tt>:th element of the object with the key <tt>Key</tt>
+in the table <tt>Tab</tt>.</p>.</td></tr><tr><td valign="top"><a href="#match-1">match/1</a></td><td><p>Continues a match started with <tt>match/3</tt>.</p>.</td></tr><tr><td valign="top"><a href="#match-2">match/2</a></td><td><p>Matches the objects in the table <tt>Tab</tt> against the pattern
+<tt>Pattern</tt>.</p>.</td></tr><tr><td valign="top"><a href="#match-3">match/3</a></td><td><p>Matches the objects in the table <tt>Tab</tt> against the pattern
+<tt>Pattern</tt> and returns a limited (<tt>Limit</tt>) number of matching
+objects.</p>.</td></tr><tr><td valign="top"><a href="#match_delete-2">match_delete/2</a></td><td><p>Deletes all objects which match the pattern <tt>Pattern</tt> from the
+table <tt>Tab</tt>.</p>.</td></tr><tr><td valign="top"><a href="#match_object-1">match_object/1</a></td><td><p>Continues a match started with <tt>match_object/3</tt>.</p>.</td></tr><tr><td valign="top"><a href="#match_object-2">match_object/2</a></td><td><p>Matches the objects in the table <tt>Tab</tt> against the pattern
+<tt>Pattern</tt>.</p>.</td></tr><tr><td valign="top"><a href="#match_object-3">match_object/3</a></td><td><p>Matches the objects in the table <tt>Tab</tt> against the pattern
+<tt>Pattern</tt> and returns a limited (<tt>Limit</tt>) number of matching
+objects.</p>.</td></tr><tr><td valign="top"><a href="#member-2">member/2</a></td><td><p>Returns <tt>true</tt> if one or more elements in the table <tt>Tab</tt> has
+the key <tt>Key</tt>, <tt>false</tt> otherwise.</p>.</td></tr><tr><td valign="top"><a href="#new-2">new/2</a></td><td><p>Creates a new table and returns a table identifier which can
+be used in subsequent operations. The table identifier can be sent
+to other processes so that a table can be shared between different
+processes within a node.</p>
+
+
+<pre><tt>Valid GEN_ETS properties for +Options+ are:</tt></pre>
+
+<ul>
+<li>
+<p>
+<tt>set</tt> The table is a set table - one key, one object, no order
+among objects. This is the default table type.
+</p>
+</li>
+<li>
+<p>
+<tt>ordered_set</tt> The table is an ordered_set table - one key, one
+object, ordered in Erlang term order, which is the order implied
+by the <tt><</tt> and <tt>></tt> operators.
+</p>
+</li>
+<li>
+<p>
+<tt>named_table</tt> If this option is present, the name <tt>Name</tt> is
+associated with the table identifier.
+</p>
+</li>
+<li>
+<p>
+<tt>{keypos,pos_integer()}</tt> Specfies which element in the stored
+tuples should be used as key. By default, it is the first
+element, i.e. <tt>Pos=1</tt>.
+</p>
+</li>
+<li>
+<p>
+<tt>public</tt> Any process may read or write to the table.
+</p>
+</li>
+<li>
+<p>
+<tt>protected</tt> The owner process can read and write to the table.
+Other processes can only read the table. This is the default
+setting for the access rights.
+</p>
+</li>
+<li>
+<p>
+<tt>private</tt> Only the owner process can read or write to the table.
+</p>
+</li>
+<li>
+<p>
+<tt>compressed</tt> If this option is present, the table data will be
+stored in a compressed format.
+</p>
+</li>
+<li>
+<p>
+<tt>async</tt> If this option is present and supported by the
+implementation, the emulator's async thread pool will be used
+when accessing the table data.
+</p>
+</li>
+<li>
+<p>
+<tt>{impl, module(), [impl_option()]}</tt> The module that implements
+GEN_ETS callback functions. Implementation specific options can
+be given. The default is <tt>{impl, gen_ets_impl_ets, []}</tt>.
+</p>
+</li>
+</ul>.</td></tr><tr><td valign="top"><a href="#next-2">next/2</a></td><td><p>Returns the next key <tt>Key2</tt>, following the key <tt>Key1</tt> in the
+table <tt>Tab</tt>. If there is no next key, <tt><em>$end_of_table</em></tt> is
+returned.</p>.</td></tr><tr><td valign="top"><a href="#prev-2">prev/2</a></td><td><p>Returns the previous key <tt>Key2</tt>, following the key <tt>Key1</tt> in
+the table <tt>Tab</tt>. If there is no previous key, <tt><em>$end_of_table</em></tt> is
+returned.</p>.</td></tr><tr><td valign="top"><a href="#repair-2">repair/2</a></td><td><p>If a table cannot be opened, you may attempt to call this
+method to resurrect as much of the contents of the table as
+possible. Some data may be lost, so be careful when calling this
+function on a table that contains important information.</p>.</td></tr><tr><td valign="top"><a href="#select-1">select/1</a></td><td><p>Continues a select started with <tt>select/3</tt>.</p>.</td></tr><tr><td valign="top"><a href="#select-2">select/2</a></td><td><p>Matches the objects in the table <tt>Tab</tt> against the spec
+<tt>Spec</tt>.</p>.</td></tr><tr><td valign="top"><a href="#select-3">select/3</a></td><td><p>Matches the objects in the table <tt>Tab</tt> against the spec <tt>Spec</tt>
+and returns a limited (<tt>Limit</tt>) number of matching objects.</p>.</td></tr><tr><td valign="top"><a href="#select_count-2">select_count/2</a></td><td><p>Counts all objects which match the spec <tt>Spec</tt> from the
+table <tt>Tab</tt> and returns the number matched.</p>.</td></tr><tr><td valign="top"><a href="#select_delete-2">select_delete/2</a></td><td><p>Deletes all objects which match the spec <tt>Spec</tt> from the
+table <tt>Tab</tt> and returns the number deleted.</p>.</td></tr><tr><td valign="top"><a href="#select_reverse-1">select_reverse/1</a></td><td><p>Continues a select reverse started with <tt>select_reverse/3</tt>.</p>.</td></tr><tr><td valign="top"><a href="#select_reverse-2">select_reverse/2</a></td><td><p>Matches in reverse the objects in the table <tt>Tab</tt> against the
+spec <tt>Spec</tt>.</p>.</td></tr><tr><td valign="top"><a href="#select_reverse-3">select_reverse/3</a></td><td><p>Matches in reverse the objects in the table <tt>Tab</tt> against the
+spec <tt>Spec</tt> and returns a limited (<tt>Limit</tt>) number of matching
+objects.</p>.</td></tr><tr><td valign="top"><a href="#tab2list-1">tab2list/1</a></td><td><p>Returns a list of all objects in the table <tt>Tab</tt>. The
+operation is <strong>not</strong> guaranteed to be atomic and isolated.</p>.</td></tr></table>
+
+
+<a name="functions"></a>
+
+##Function Details##
+
+<a name="all-0"></a>
+
+###all/0##
+
+
+<pre>all() -> [<a href="#type-tab">tab()</a>]</pre>
+<br></br>
+
+
+<p>Returns a list of all tables at the node.</p>
+
+
+__See also:__ [ets:all/0](ets.md#all-0).<a name="behaviour_info-1"></a>
+
+###behaviour_info/1##
+
+
+`behaviour_info(Other) -> any()`
+
+<a name="delete-1"></a>
+
+###delete/1##
+
+
+<pre>delete(Tab::<a href="#type-tab">tab()</a>) -> true</pre>
+<br></br>
+
+
+<p>Deletes the entire table <tt>Tab</tt>.</p>
+
+
+__See also:__ [ets:delete/1](ets.md#delete-1).<a name="delete-2"></a>
+
+###delete/2##
+
+
+<pre>delete(Tab::<a href="#type-tab">tab()</a>, Key::<a href="#type-key">key()</a>) -> true</pre>
+<br></br>
+
+
+<p>Deletes all objects with the key <tt>Key</tt> from the table <tt>Tab</tt>.</p>
+
+
+__See also:__ [ets:delete/2](ets.md#delete-2).<a name="delete_all_objects-1"></a>
+
+###delete_all_objects/1##
+
+
+<pre>delete_all_objects(Tab::<a href="#type-tab">tab()</a>) -> true</pre>
+<br></br>
+
+
+<p>Delete all objects in the table <tt>Tab</tt>. The operation is
+guaranteed to be atomic and isolated. This function only applies
+to the <tt>ets</tt> implementation.</p>
+
+
+__See also:__ [ets:delete_all_objects/1](ets.md#delete_all_objects-1).<a name="destroy-2"></a>
+
+###destroy/2##
+
+
+<pre>destroy(Name::<a href="#type-name">name()</a>, Opts::<a href="#type-opts">opts()</a>) -> true</pre>
+<br></br>
+
+
+<p>Destroy the contents of the specified table.</p>
+<a name="first-1"></a>
+
+###first/1##
+
+
+<pre>first(Tab::<a href="#type-tab">tab()</a>) -> <a href="#type-key">key()</a> | '$end_of_table'</pre>
+<br></br>
+
+
+<p>Returns the first key <tt>Key</tt> in the table <tt>Tab</tt>. If the table
+is empty, <tt><em>$end_of_table</em></tt> will be returned.</p>
+
+
+__See also:__ [ets:first/1](ets.md#first-1).<a name="foldl-3"></a>
+
+###foldl/3##
+
+
+<pre>foldl(Fun, Acc0::term(), Tab::<a href="#type-tab">tab()</a>) -> Acc1::term()</pre>
+<ul class="definitions"><li><pre>Fun = fun((Element::term(), AccIn::term()) -&gt; AccOut::term())</pre></li></ul>
+
+<p>Fold from left to right over the elements of the table.</p>
+
+
+__See also:__ [ets:foldl/3](ets.md#foldl-3).<a name="foldr-3"></a>
+
+###foldr/3##
+
+
+<pre>foldr(Fun, Acc0::term(), Tab::<a href="#type-tab">tab()</a>) -> Acc1::term()</pre>
+<ul class="definitions"><li><pre>Fun = fun((Element::term(), AccIn::term()) -&gt; AccOut::term())</pre></li></ul>
+
+<p>Fold from right to left over the elements of the table.</p>
+
+
+__See also:__ [ets:foldr/3](ets.md#foldr-3).<a name="info-1"></a>
+
+###info/1##
+
+
+<pre>info(Tab::<a href="#type-tab">tab()</a>) -> [{<a href="#type-item">item()</a>, term()}]</pre>
+<br></br>
+
+
+<p>Returns information about the table <tt>Tab</tt> as a list of <tt>{Item,
+ Value}</tt> tuples.</p>
+
+
+__See also:__ [info/2](#info-2).<a name="info-2"></a>
+
+###info/2##
+
+
+<pre>info(Tab::<a href="#type-tab">tab()</a>, Item::<a href="#type-item">item()</a>) -> term()</pre>
+<br></br>
+
+
+<p>Returns the information associated with <tt>Item</tt> for the table <tt>Tab</tt>.</p>
+
+
+<pre><tt>Valid +Item+ options are:</tt></pre>
+
+<ul>
+<li>
+<p>
+<tt>owner</tt>
+</p>
+</li>
+<li>
+<p>
+<tt>name</tt>
+</p>
+</li>
+<li>
+<p>
+<tt>named_table</tt> <em>only the ets implementation</em>
+</p>
+</li>
+<li>
+<p>
+<tt>type</tt>
+</p>
+</li>
+<li>
+<p>
+<tt>keypos</tt>
+</p>
+</li>
+<li>
+<p>
+<tt>protection</tt>
+</p>
+</li>
+<li>
+<p>
+<tt>compressed</tt>
+</p>
+</li>
+<li>
+<p>
+<tt>async</tt> <em>only the drv implementation</em>
+</p>
+</li>
+<li>
+<p>
+<tt>memory</tt> <em>only the ets implementation</em>
+</p>
+</li>
+<li>
+<p>
+<tt>size</tt> <em>only the ets implementation</em>
+</p>
+</li>
+</ul>
+
+
+__See also:__ [ets:info/2](ets.md#info-2).<a name="insert-2"></a>
+
+###insert/2##
+
+
+<pre>insert(Tab::<a href="#type-tab">tab()</a>, ObjOrObjs::<a href="#type-object">object()</a> | [<a href="#type-object">object()</a>]) -> true</pre>
+<br></br>
+
+
+<p>Inserts the object or all of the objects in the list
+<tt>ObjOrObjs</tt> into the table <tt>Tab</tt>.</p>
+
+
+__See also:__ [ets:insert/2](ets.md#insert-2).<a name="insert_new-2"></a>
+
+###insert_new/2##
+
+
+<pre>insert_new(Tab::<a href="#type-tab">tab()</a>, ObjOrObjs::<a href="#type-object">object()</a> | [<a href="#type-object">object()</a>]) -> true</pre>
+<br></br>
+
+
+<p>This function works exactly like <tt>insert/2</tt>, with the
+exception that instead of overwriting objects with the same key, it
+simply returns false. This function only applies to the <tt>ets</tt>
+implementation.</p>
+
+
+__See also:__ [ets:insert_new/2](ets.md#insert_new-2).<a name="last-1"></a>
+
+###last/1##
+
+
+<pre>last(Tab::<a href="#type-tab">tab()</a>) -> <a href="#type-key">key()</a> | '$end_of_table'</pre>
+<br></br>
+
+
+<p>Returns the last key <tt>Key</tt> in the table <tt>Tab</tt>. If the table
+is empty, <tt><em>$end_of_table</em></tt> will be returned.</p>
+
+
+__See also:__ [ets:last/1](ets.md#last-1).<a name="lookup-2"></a>
+
+###lookup/2##
+
+
+<pre>lookup(Tab::<a href="#type-tab">tab()</a>, Key::<a href="#type-key">key()</a>) -> [<a href="#type-object">object()</a>]</pre>
+<br></br>
+
+
+<p>Returns a list of all objects with the key <tt>Key</tt> in the table
+<tt>Tab</tt>.</p>
+
+
+__See also:__ [ets:lookup/2](ets.md#lookup-2).<a name="lookup_element-3"></a>
+
+###lookup_element/3##
+
+
+<pre>lookup_element(Tab::<a href="#type-tab">tab()</a>, Key::<a href="#type-key">key()</a>, Pos::<a href="#type-pos">pos()</a>) -> term()</pre>
+<br></br>
+
+
+<p>Returns the <tt>Pos</tt>:th element of the object with the key <tt>Key</tt>
+in the table <tt>Tab</tt>.</p>
+
+
+__See also:__ [ets:lookup_element/3](ets.md#lookup_element-3).<a name="match-1"></a>
+
+###match/1##
+
+
+<pre>match(X1::<a href="#type-cont">cont()</a> | '$end_of_table') -> {[<a href="#type-match">match()</a>], <a href="#type-cont">cont()</a> | '$end_of_table'} | '$end_of_table'</pre>
+<br></br>
+
+
+<p>Continues a match started with <tt>match/3</tt>.</p>
+
+
+__See also:__ [ets:match/1](ets.md#match-1).<a name="match-2"></a>
+
+###match/2##
+
+
+<pre>match(Tab::<a href="#type-tab">tab()</a>, Pattern::<a href="#type-match_pattern">match_pattern()</a>) -> [<a href="#type-match">match()</a>]</pre>
+<br></br>
+
+
+<p>Matches the objects in the table <tt>Tab</tt> against the pattern
+<tt>Pattern</tt>.</p>
+
+
+__See also:__ [ets:match/2](ets.md#match-2).<a name="match-3"></a>
+
+###match/3##
+
+
+<pre>match(Tab::<a href="#type-tab">tab()</a>, Pattern::<a href="#type-match_pattern">match_pattern()</a>, Limit::<a href="#type-limit">limit()</a>) -> {[<a href="#type-match">match()</a>], <a href="#type-cont">cont()</a> | '$end_of_table'} | '$end_of_table'</pre>
+<br></br>
+
+
+<p>Matches the objects in the table <tt>Tab</tt> against the pattern
+<tt>Pattern</tt> and returns a limited (<tt>Limit</tt>) number of matching
+objects.</p>
+
+
+__See also:__ [ets:match/3](ets.md#match-3).<a name="match_delete-2"></a>
+
+###match_delete/2##
+
+
+<pre>match_delete(Tab::<a href="#type-tab">tab()</a>, Pattern::<a href="#type-match_pattern">match_pattern()</a>) -> true</pre>
+<br></br>
+
+
+<p>Deletes all objects which match the pattern <tt>Pattern</tt> from the
+table <tt>Tab</tt>.</p>
+
+
+__See also:__ [ets:match_delete/2](ets.md#match_delete-2).<a name="match_object-1"></a>
+
+###match_object/1##
+
+
+<pre>match_object(X1::<a href="#type-cont">cont()</a> | '$end_of_table') -> {[<a href="#type-match">match()</a>], <a href="#type-cont">cont()</a> | '$end_of_table'} | '$end_of_table'</pre>
+<br></br>
+
+
+<p>Continues a match started with <tt>match_object/3</tt>.</p>
+
+
+__See also:__ [ets:match_object/1](ets.md#match_object-1).<a name="match_object-2"></a>
+
+###match_object/2##
+
+
+<pre>match_object(Tab::<a href="#type-tab">tab()</a>, Pattern::<a href="#type-match_pattern">match_pattern()</a>) -> [<a href="#type-match">match()</a>]</pre>
+<br></br>
+
+
+<p>Matches the objects in the table <tt>Tab</tt> against the pattern
+<tt>Pattern</tt>.</p>
+
+
+__See also:__ [ets:match_object/2](ets.md#match_object-2).<a name="match_object-3"></a>
+
+###match_object/3##
+
+
+<pre>match_object(Tab::<a href="#type-tab">tab()</a>, Pattern::<a href="#type-match_pattern">match_pattern()</a>, Limit::<a href="#type-limit">limit()</a>) -> {[<a href="#type-match">match()</a>], <a href="#type-cont">cont()</a> | '$end_of_table'} | '$end_of_table'</pre>
+<br></br>
+
+
+<p>Matches the objects in the table <tt>Tab</tt> against the pattern
+<tt>Pattern</tt> and returns a limited (<tt>Limit</tt>) number of matching
+objects.</p>
+
+
+__See also:__ [ets:match_object/3](ets.md#match_object-3).<a name="member-2"></a>
+
+###member/2##
+
+
+<pre>member(Tab::<a href="#type-tab">tab()</a>, Key::<a href="#type-key">key()</a>) -> true | false</pre>
+<br></br>
+
+
+<p>Returns <tt>true</tt> if one or more elements in the table <tt>Tab</tt> has
+the key <tt>Key</tt>, <tt>false</tt> otherwise.</p>
+
+
+__See also:__ [ets:member/2](ets.md#member-2).<a name="new-2"></a>
+
+###new/2##
+
+
+<pre>new(Name::<a href="#type-name">name()</a>, Opts::<a href="#type-opts">opts()</a>) -> <a href="#type-tab">tab()</a></pre>
+<br></br>
+
+
+<p>Creates a new table and returns a table identifier which can
+be used in subsequent operations. The table identifier can be sent
+to other processes so that a table can be shared between different
+processes within a node.</p>
+
+
+<pre><tt>Valid GEN_ETS properties for +Options+ are:</tt></pre>
+
+<ul>
+<li>
+<p>
+<tt>set</tt> The table is a set table - one key, one object, no order
+among objects. This is the default table type.
+</p>
+</li>
+<li>
+<p>
+<tt>ordered_set</tt> The table is an ordered_set table - one key, one
+object, ordered in Erlang term order, which is the order implied
+by the <tt><</tt> and <tt>></tt> operators.
+</p>
+</li>
+<li>
+<p>
+<tt>named_table</tt> If this option is present, the name <tt>Name</tt> is
+associated with the table identifier.
+</p>
+</li>
+<li>
+<p>
+<tt>{keypos,pos_integer()}</tt> Specfies which element in the stored
+tuples should be used as key. By default, it is the first
+element, i.e. <tt>Pos=1</tt>.
+</p>
+</li>
+<li>
+<p>
+<tt>public</tt> Any process may read or write to the table.
+</p>
+</li>
+<li>
+<p>
+<tt>protected</tt> The owner process can read and write to the table.
+Other processes can only read the table. This is the default
+setting for the access rights.
+</p>
+</li>
+<li>
+<p>
+<tt>private</tt> Only the owner process can read or write to the table.
+</p>
+</li>
+<li>
+<p>
+<tt>compressed</tt> If this option is present, the table data will be
+stored in a compressed format.
+</p>
+</li>
+<li>
+<p>
+<tt>async</tt> If this option is present and supported by the
+implementation, the emulator's async thread pool will be used
+when accessing the table data.
+</p>
+</li>
+<li>
+<p>
+<tt>{impl, module(), [impl_option()]}</tt> The module that implements
+GEN_ETS callback functions. Implementation specific options can
+be given. The default is <tt>{impl, gen_ets_impl_ets, []}</tt>.
+</p>
+</li>
+</ul>
+
+
+__See also:__ [ets:new/2](ets.md#new-2).<a name="next-2"></a>
+
+###next/2##
+
+
+<pre>next(Tab::<a href="#type-tab">tab()</a>, Key::<a href="#type-key">key()</a>) -> <a href="#type-key">key()</a> | '$end_of_table'</pre>
+<br></br>
+
+
+<p>Returns the next key <tt>Key2</tt>, following the key <tt>Key1</tt> in the
+table <tt>Tab</tt>. If there is no next key, <tt><em>$end_of_table</em></tt> is
+returned.</p>
+
+
+__See also:__ [ets:next/2](ets.md#next-2).<a name="prev-2"></a>
+
+###prev/2##
+
+
+<pre>prev(Tab::<a href="#type-tab">tab()</a>, Key::<a href="#type-key">key()</a>) -> <a href="#type-key">key()</a> | '$end_of_table'</pre>
+<br></br>
+
+
+<p>Returns the previous key <tt>Key2</tt>, following the key <tt>Key1</tt> in
+the table <tt>Tab</tt>. If there is no previous key, <tt><em>$end_of_table</em></tt> is
+returned.</p>
+
+
+__See also:__ [ets:prev/2](ets.md#prev-2).<a name="repair-2"></a>
+
+###repair/2##
+
+
+<pre>repair(Name::<a href="#type-name">name()</a>, Opts::<a href="#type-opts">opts()</a>) -> true</pre>
+<br></br>
+
+
+<p>If a table cannot be opened, you may attempt to call this
+method to resurrect as much of the contents of the table as
+possible. Some data may be lost, so be careful when calling this
+function on a table that contains important information.</p>
+<a name="select-1"></a>
+
+###select/1##
+
+
+<pre>select(X1::<a href="#type-cont">cont()</a> | '$end_of_table') -> {[<a href="#type-match">match()</a>], <a href="#type-cont">cont()</a> | '$end_of_table'} | '$end_of_table'</pre>
+<br></br>
+
+
+<p>Continues a select started with <tt>select/3</tt>.</p>
+
+
+__See also:__ [ets:select/1](ets.md#select-1).<a name="select-2"></a>
+
+###select/2##
+
+
+<pre>select(Tab::<a href="#type-tab">tab()</a>, Spec::<a href="#type-match_spec">match_spec()</a>) -> [<a href="#type-match">match()</a>]</pre>
+<br></br>
+
+
+<p>Matches the objects in the table <tt>Tab</tt> against the spec
+<tt>Spec</tt>.</p>
+
+
+__See also:__ [ets:select/2](ets.md#select-2).<a name="select-3"></a>
+
+###select/3##
+
+
+<pre>select(Tab::<a href="#type-tab">tab()</a>, Spec::<a href="#type-match_spec">match_spec()</a>, Limit::<a href="#type-limit">limit()</a>) -> {[<a href="#type-match">match()</a>], <a href="#type-cont">cont()</a> | '$end_of_table'} | '$end_of_table'</pre>
+<br></br>
+
+
+<p>Matches the objects in the table <tt>Tab</tt> against the spec <tt>Spec</tt>
+and returns a limited (<tt>Limit</tt>) number of matching objects.</p>
+
+
+__See also:__ [ets:select/3](ets.md#select-3).<a name="select_count-2"></a>
+
+###select_count/2##
+
+
+<pre>select_count(Tab::<a href="#type-tab">tab()</a>, Spec::<a href="#type-match_pattern">match_pattern()</a>) -> pos_integer()</pre>
+<br></br>
+
+
+<p>Counts all objects which match the spec <tt>Spec</tt> from the
+table <tt>Tab</tt> and returns the number matched.</p>
+
+
+__See also:__ [ets:select_count/2](ets.md#select_count-2).<a name="select_delete-2"></a>
+
+###select_delete/2##
+
+
+<pre>select_delete(Tab::<a href="#type-tab">tab()</a>, Spec::<a href="#type-match_pattern">match_pattern()</a>) -> pos_integer()</pre>
+<br></br>
+
+
+<p>Deletes all objects which match the spec <tt>Spec</tt> from the
+table <tt>Tab</tt> and returns the number deleted.</p>
+
+
+__See also:__ [ets:select_delete/2](ets.md#select_delete-2).<a name="select_reverse-1"></a>
+
+###select_reverse/1##
+
+
+<pre>select_reverse(X1::<a href="#type-cont">cont()</a> | '$end_of_table') -> {[<a href="#type-match">match()</a>], <a href="#type-cont">cont()</a> | '$end_of_table'} | '$end_of_table'</pre>
+<br></br>
+
+
+<p>Continues a select reverse started with <tt>select_reverse/3</tt>.</p>
+
+
+__See also:__ [ets:select_reverse/1](ets.md#select_reverse-1).<a name="select_reverse-2"></a>
+
+###select_reverse/2##
+
+
+<pre>select_reverse(Tab::<a href="#type-tab">tab()</a>, Spec::<a href="#type-match_spec">match_spec()</a>) -> [<a href="#type-match">match()</a>]</pre>
+<br></br>
+
+
+<p>Matches in reverse the objects in the table <tt>Tab</tt> against the
+spec <tt>Spec</tt>.</p>
+
+
+__See also:__ [ets:select_reverse/2](ets.md#select_reverse-2).<a name="select_reverse-3"></a>
+
+###select_reverse/3##
+
+
+<pre>select_reverse(Tab::<a href="#type-tab">tab()</a>, Spec::<a href="#type-match_spec">match_spec()</a>, Limit::<a href="#type-limit">limit()</a>) -> {[<a href="#type-match">match()</a>], <a href="#type-cont">cont()</a> | '$end_of_table'} | '$end_of_table'</pre>
+<br></br>
+
+
+<p>Matches in reverse the objects in the table <tt>Tab</tt> against the
+spec <tt>Spec</tt> and returns a limited (<tt>Limit</tt>) number of matching
+objects.</p>
+
+
+__See also:__ [ets:select_reverse/3](ets.md#select_reverse-3).<a name="tab2list-1"></a>
+
+###tab2list/1##
+
+
+<pre>tab2list(Tab::<a href="#type-tab">tab()</a>) -> [<a href="#type-object">object()</a>]</pre>
+<br></br>
+
+
+<p>Returns a list of all objects in the table <tt>Tab</tt>. The
+operation is <strong>not</strong> guaranteed to be atomic and isolated.</p>
+
+
+__See also:__ [ets:tab2list/1](ets.md#tab2list-1).
264 doc/gen_ets_impl_ets.md
@@ -0,0 +1,264 @@
+
+
+#Module gen_ets_impl_ets#
+* [Function Index](#index)
+* [Function Details](#functions)
+
+
+<a name="index"></a>
+
+##Function Index##
+
+
+<table width="100%" border="1" cellspacing="0" cellpadding="2" summary="function index"><tr><td valign="top"><a href="#delete-1">delete/1</a></td><td></td></tr><tr><td valign="top"><a href="#delete-2">delete/2</a></td><td></td></tr><tr><td valign="top"><a href="#delete_all_objects-1">delete_all_objects/1</a></td><td></td></tr><tr><td valign="top"><a href="#destroy-2">destroy/2</a></td><td></td></tr><tr><td valign="top"><a href="#first-1">first/1</a></td><td></td></tr><tr><td valign="top"><a href="#foldl-3">foldl/3</a></td><td></td></tr><tr><td valign="top"><a href="#foldr-3">foldr/3</a></td><td></td></tr><tr><td valign="top"><a href="#info_memory-1">info_memory/1</a></td><td></td></tr><tr><td valign="top"><a href="#info_size-1">info_size/1</a></td><td></td></tr><tr><td valign="top"><a href="#insert-2">insert/2</a></td><td></td></tr><tr><td valign="top"><a href="#insert_new-2">insert_new/2</a></td><td></td></tr><tr><td valign="top"><a href="#last-1">last/1</a></td><td></td></tr><tr><td valign="top"><a href="#lookup-2">lookup/2</a></td><td></td></tr><tr><td valign="top"><a href="#lookup_element-3">lookup_element/3</a></td><td></td></tr><tr><td valign="top"><a href="#match-1">match/1</a></td><td></td></tr><tr><td valign="top"><a href="#match-2">match/2</a></td><td></td></tr><tr><td valign="top"><a href="#match-3">match/3</a></td><td></td></tr><tr><td valign="top"><a href="#match_delete-2">match_delete/2</a></td><td></td></tr><tr><td valign="top"><a href="#match_object-1">match_object/1</a></td><td></td></tr><tr><td valign="top"><a href="#match_object-2">match_object/2</a></td><td></td></tr><tr><td valign="top"><a href="#match_object-3">match_object/3</a></td><td></td></tr><tr><td valign="top"><a href="#member-2">member/2</a></td><td></td></tr><tr><td valign="top"><a href="#next-2">next/2</a></td><td></td></tr><tr><td valign="top"><a href="#open-2">open/2</a></td><td></td></tr><tr><td valign="top"><a href="#prev-2">prev/2</a></td><td></td></tr><tr><td valign="top"><a href="#repair-2">repair/2</a></td><td></td></tr><tr><td valign="top"><a href="#select-1">select/1</a></td><td></td></tr><tr><td valign="top"><a href="#select-2">select/2</a></td><td></td></tr><tr><td valign="top"><a href="#select-3">select/3</a></td><td></td></tr><tr><td valign="top"><a href="#select_count-2">select_count/2</a></td><td></td></tr><tr><td valign="top"><a href="#select_delete-2">select_delete/2</a></td><td></td></tr><tr><td valign="top"><a href="#select_reverse-1">select_reverse/1</a></td><td></td></tr><tr><td valign="top"><a href="#select_reverse-2">select_reverse/2</a></td><td></td></tr><tr><td valign="top"><a href="#select_reverse-3">select_reverse/3</a></td><td></td></tr><tr><td valign="top"><a href="#tab2list-1">tab2list/1</a></td><td></td></tr></table>
+
+
+<a name="functions"></a>
+
+##Function Details##
+
+<a name="delete-1"></a>
+
+###delete/1##
+
+
+`delete(Tid) -> any()`
+
+<a name="delete-2"></a>
+
+###delete/2##
+
+
+`delete(Tid, Key) -> any()`
+
+<a name="delete_all_objects-1"></a>
+
+###delete_all_objects/1##
+
+
+`delete_all_objects(Tid) -> any()`
+
+<a name="destroy-2"></a>
+
+###destroy/2##
+
+
+`destroy(Tid, Opts) -> any()`
+
+<a name="first-1"></a>
+
+###first/1##
+
+
+`first(Tid) -> any()`
+
+<a name="foldl-3"></a>
+
+###foldl/3##
+
+
+`foldl(Function, Acc0, Tid) -> any()`
+
+<a name="foldr-3"></a>
+
+###foldr/3##
+
+
+`foldr(Function, Acc0, Tid) -> any()`
+
+<a name="info_memory-1"></a>
+
+###info_memory/1##
+
+
+`info_memory(Tid) -> any()`
+
+<a name="info_size-1"></a>
+
+###info_size/1##
+
+
+`info_size(Tid) -> any()`
+
+<a name="insert-2"></a>
+
+###insert/2##
+
+
+`insert(Tid, ObjOrObjs) -> any()`
+
+<a name="insert_new-2"></a>
+
+###insert_new/2##
+
+
+`insert_new(Tid, ObjOrObjs) -> any()`
+
+<a name="last-1"></a>
+
+###last/1##
+
+
+`last(Tid) -> any()`
+
+<a name="lookup-2"></a>
+
+###lookup/2##
+
+
+`lookup(Tid, Key) -> any()`
+
+<a name="lookup_element-3"></a>
+
+###lookup_element/3##
+
+
+`lookup_element(Tid, Key, Pos) -> any()`
+
+<a name="match-1"></a>
+
+###match/1##
+
+
+`match(Cont) -> any()`
+
+<a name="match-2"></a>
+
+###match/2##
+
+
+`match(Tid, Pattern) -> any()`
+
+<a name="match-3"></a>
+
+###match/3##
+
+
+`match(Tid, Pattern, Limit) -> any()`
+
+<a name="match_delete-2"></a>
+
+###match_delete/2##
+
+
+`match_delete(Tid, Pattern) -> any()`
+
+<a name="match_object-1"></a>
+
+###match_object/1##
+
+
+`match_object(Cont) -> any()`
+
+<a name="match_object-2"></a>
+
+###match_object/2##
+
+
+`match_object(Tid, Pattern) -> any()`
+
+<a name="match_object-3"></a>
+
+###match_object/3##
+
+
+`match_object(Tid, Pattern, Limit) -> any()`
+
+<a name="member-2"></a>
+
+###member/2##
+
+
+`member(Tid, Key) -> any()`
+
+<a name="next-2"></a>
+
+###next/2##
+
+
+`next(Tid, Key) -> any()`
+
+<a name="open-2"></a>
+
+###open/2##
+
+
+`open(Tid, Opts) -> any()`
+
+<a name="prev-2"></a>
+
+###prev/2##
+
+
+`prev(Tid, Key) -> any()`
+
+<a name="repair-2"></a>
+
+###repair/2##
+
+
+`repair(Tid, Opts) -> any()`
+
+<a name="select-1"></a>
+
+###select/1##
+
+
+`select(Cont) -> any()`
+
+<a name="select-2"></a>
+
+###select/2##
+
+
+`select(Tid, Spec) -> any()`
+
+<a name="select-3"></a>
+
+###select/3##
+
+
+`select(Tid, Spec, Limit) -> any()`
+
+<a name="select_count-2"></a>
+
+###select_count/2##
+
+
+`select_count(Tid, Spec) -> any()`
+
+<a name="select_delete-2"></a>
+
+###select_delete/2##
+
+
+`select_delete(Tid, Spec) -> any()`
+
+<a name="select_reverse-1"></a>
+
+###select_reverse/1##
+
+
+`select_reverse(Cont) -> any()`
+
+<a name="select_reverse-2"></a>
+
+###select_reverse/2##
+
+
+`select_reverse(Tid, Spec) -> any()`
+
+<a name="select_reverse-3"></a>
+
+###select_reverse/3##
+
+
+`select_reverse(Tid, Spec, Limit) -> any()`
+
+<a name="tab2list-1"></a>
+
+###tab2list/1##
+
+
+`tab2list(Tid) -> any()`
+
372 doc/overview.edoc
@@ -0,0 +1,372 @@
+%% -*- Doc -*-
+%% vim: set syntax=asciidoc:
+@author Joseph Wayne Norton <norton@alum.mit.edu>
+@copyright 2011-2012 by Joseph Wayne Norton
+@title GEN_ETS - GEN(eric) Erlang Term Storage
+@doc
+GEN_ETS is an generic wrapper for Erlang Term Storage with a callback
+interface for a backend implementation.
+
+For testing purposes, GEN_ETS supports a default backend
+implementation:
+
+- +ets+ Erlang ETS backend
+
+GEN_ETS is not intended to be an exact clone of ETS. The currently
+supported ETS APIs are:
+
+- +all/0+
+- +delete/1+
+- +delete/2+
+- +delete_all_objects/1+
+- +first/1+
+- +foldl/3+
+- +foldr/3+
+- +info/1+ _only a subset of items_
+- +info/2+ _only a subset of items_
+- +insert/2+
+- +insert_new/2+
+- +last/1+
+- +lookup/2+
+- +lookup_element/3+
+- +match/1+
+- +match/2+
+- +match/3+
+- +match_delete/2+
+- +match_object/1+
+- +match_object/2+
+- +match_object/3+
+- +member/2+
+- +new/2+
+- +next/2+
+- +prev/2+
+- +select/1+
+- +select/2+
+- +select/3+
+- +select_count/2+
+- +select_delete/2+
+- +select_reverse/1+
+- +select_reverse/2+
+- +select_reverse/3+
+- +tab2list/1+
+
+_This repository is experimental in nature - use at your own risk and
+please contribute if you find GEN_ETS useful._
+
+== Quick Start Recipe
+
+To download and build the gen_ets application in one shot, please follow
+this recipe:
+
+------
+$ mkdir working-directory-name
+$ cd working-directory-name
+$ git clone https://github.com/norton/gen_ets.git gen_ets
+$ cd gen_ets
+$ ./rebar get-deps
+$ ./rebar clean
+$ ./rebar compile
+------
+
+_OR_ if QuickCheck is available then follow the this recipe:
+
+------
+$ mkdir working-directory-name
+$ cd working-directory-name
+$ git clone https://github.com/norton/gen_ets.git gen_ets
+$ cd gen_ets
+$ ./rebar get-deps
+$ ./rebar clean
+$ ./rebar compile -D QC -D QC_EQC
+$ ./rebar test-compile -D QC -D QC_EQC
+$ (cd .test; erl -smp +A 5 -pz ../../qc/ebin)
+
+1> qc_statem_gen_ets:qc_run(500, []).
+ :
+ :
+OK, passed 500 tests
+
+100.0% {1,attempts}
+
+7.11% {delete,ok}
+6.78% {new,ok}
+3.91% {insert_new,ok}
+3.83% {select_reverse31,ok}
+3.76% {select31,ok}
+3.69% {tab2list,ok}
+3.69% {match31,ok}
+3.69% {first,ok}
+3.67% {delete_all_objects,ok}
+3.66% {foldl,ok}
+3.63% {select,ok}
+3.63% {member,ok}
+3.61% {select_count,ok}
+3.61% {last,ok}
+3.61% {foldr,ok}
+3.57% {insert,ok}
+3.50% {match_object31,ok}
+3.49% {match_delete,ok}
+3.44% {lookup,ok}
+3.42% {select_delete,ok}
+3.36% {match_object,ok}
+3.34% {select_reverse,ok}
+3.19% {match,ok}
+2.92% {lookup_element,{error,badarg}}
+2.17% {prev,ok}
+1.88% {next,ok}
+1.57% {next,{error,badarg}}
+1.56% {prev,{error,badarg}}
+0.72% {lookup_element,ok}
+true
+------
+
+For an alternative recipe with other "features" albeit more complex,
+please read further.
+
+== Documentation
+
+=== Where should I start?
+
+This README is the only bit of documentation right now.
+
+The QC (a.k.a. QuickCheck, PropEr, etc.) tests underneath the
+"tests/qc" directory should be helpful for understanding the
+specification and behavior of ETS and GEN_ETS. NIF-based
+implementations.
+
+=== What is ETS and DETS?
+
+ETS and DETS are Erlang/OTP\'s standard library modules for Erlang
+term storage. ETS is a memory-based implementation. DETS is a
+disk-based implementation.
+
+See http://www.erlang.org/doc/man/ets.html and
+http://www.erlang.org/doc/man/dets.html for further details.
+
+== To download
+
+1. Configure your e-mail and name for Git
++
+------
+$ git config \--global user.email "you@example.com"
+$ git config \--global user.name "Your Name"
+------
+
+2. Install Repo
++
+------
+$ mkdir -p ~/bin
+$ wget -O - https://dl-ssl.google.com/dl/googlesource/git-repo/repo > ~/bin/repo
+$ chmod a+x ~/bin/repo
+------
+
+3. Create working directory
++
+------
+$ mkdir working-directory-name
+$ cd working-directory-name
+$ repo init -u https://github.com/norton/manifests.git -m gen_ets-default.xml
+------
++
+NOTE: Your "Git" identity is needed during the init step. Please
+enter the name and email of your GitHub account if you have one. Team
+members having read-write access are recommended to use "repo init -u
+git@github.com:norton/manifests.git -m gen_ets-default-rw.xml".
++
+TIP: If you want to checkout the latest development version, please
+append " -b dev" to the repo init command.
+
+4. Download Git repositories
++
+------
+$ cd working-directory-name
+$ repo sync
+------
+
+For futher information and help for related tools, please refer to the
+following links:
+
+- Erlang - http://www.erlang.org/
+ * *R14 or newer, R15B02 has been tested recently*
+- Git - http://git-scm.com/
+ * *Git 1.5.4 or newer, Git 1.7.12 has been tested recently*
+ * _required for Repo and GitHub_
+- GitHub - https://github.com
+- Python - http://www.python.org
+ * *Python 2.4 or newer, Python 2.7.2 has been tested recently
+ (CAUTION: Python 3.x might be too new)*
+* _required for Repo_
+ - Rebar - https://github.com/basho/rebar/wiki
+ - Repo - http://source.android.com/source/git-repo.html
+
+== To build - basic recipe
+
+1. Get and install an erlang system http://www.erlang.org
+
+2. Build
++
+------
+$ cd working-directory-name
+$ make compile
+------
+
+== To build - optional features
+
+A. Dialyzer Testing _basic recipe_
+ 1. Build Dialyzer\'s PLT _(required once)_
++
+------
+$ cd working-directory-name
+$ make build-plt
+------
++
+TIP: Check Makefile and dialyzer\'s documentation for further
+information.
+
+ 2. Dialyze with specs
++
+------
+$ cd working-directory-name
+$ make dialyze
+------
++
+CAUTION: If you manually run dialyzer with the "-r" option, execute
+"make clean compile" first to avoid finding duplicate beam files
+underneath rebar\'s .test directory. Check Makefile for further
+information.
+
+ 3. Dialyze without specs
++
+------
+$ cd working-directory-name
+$ make dialyze-nospec
+------
+
+== To test - QuickCheck
+
+1. Make sure QuickCheck is in your Erlang code path. One simple way
+ to accomplish this is by adding the code path to your +~/.erlang+
+ resource file.
++
+------
+true = code:add_pathz(os:getenv("HOME")++"/.erlang.d/deps/quviq/eqc-X.Y.Z/ebin").
+------
+
+2. Compile for QuickCheck
++
+------
+$ cd working-directory-name
+$ make clean
+$ make eqc-compile
+------
+
+3. Run 5,000 QuickCheck tests
++
+------
+$ cd working-directory-name/deps/gen_ets/.test
+$ erl -smp +A 5 -pz -pz ../../qc/ebin
+
+1> qc_statem_gen_ets:qc_run(5000).
+....
+OK, passed 5000 tests
+
+100.0% {1,attempts}
+
+7.11% {delete,ok}
+6.78% {new,ok}
+3.91% {insert_new,ok}
+3.83% {select_reverse31,ok}
+3.76% {select31,ok}
+3.69% {tab2list,ok}
+3.69% {match31,ok}
+3.69% {first,ok}
+3.67% {delete_all_objects,ok}
+3.66% {foldl,ok}
+3.63% {select,ok}
+3.63% {member,ok}
+3.61% {select_count,ok}
+3.61% {last,ok}
+3.61% {foldr,ok}
+3.57% {insert,ok}
+3.50% {match_object31,ok}
+3.49% {match_delete,ok}
+3.44% {lookup,ok}
+3.42% {select_delete,ok}
+3.36% {match_object,ok}
+3.34% {select_reverse,ok}
+3.19% {match,ok}
+2.92% {lookup_element,{error,badarg}}
+2.17% {prev,ok}
+1.88% {next,ok}
+1.57% {next,{error,badarg}}
+1.56% {prev,{error,badarg}}
+0.72% {lookup_element,ok}
+true
+.......
+------
++
+TIP: For testing LevelDB directly using the C bindings, try
+ +qc_statemc_gen_ets:qc_run(5000)+.
+
+== To test - PropEr
+
+1. Make sure PropEr is in your Erlang code path. One simple way to
+ accomplish this is by adding the code path to your +~/.erlang+
+ resource file.
++
+------
+true = code:add_pathz(os:getenv("HOME")++"/.erlang.d/deps/proper/ebin").
+------
+
+2. Compile for PropEr
++
+------
+$ cd working-directory-name
+$ make clean
+$ make proper-compile
+------
+
+3. Run 5,000 PropEr tests
++
+------
+$ cd working-directory-name/deps/gen_ets/.test
+$ erl -smp +A 5 -pz -pz ../../qc/ebin
+
+1> qc_statem_gen_ets:qc_run(5000).
+....
+OK: Passed 5000 test(s).
+
+11% {new,ok}
+8% {delete,ok}
+4% {member,ok}
+4% {select,ok}
+4% {select_count,ok}
+4% {select_reverse,ok}
+4% {lookup,ok}
+4% {match_object,ok}
+4% {tab2list,ok}
+4% {last,ok}
+4% {match,ok}
+4% {foldl,ok}
+4% {match_delete,ok}
+3% {prev,ok}
+3% {select31,ok}
+3% {select_delete,ok}
+3% {foldr,ok}
+3% {insert,ok}
+3% {first,ok}
+3% {next,ok}
+3% {lookup_element,{error,badarg}}
+1% {insert_new,ok}
+0% {prev,{error,badarg}}
+0% {lookup_element,ok}
+0% {next,{error,badarg}}
+true
+.......
+------
+
+== Roadmap
+
+_TODO_
+
+@end
39 include/gen_ets.hrl
@@ -0,0 +1,39 @@
+%%% The MIT License