Copyright (c) 2011-2013 by Joseph Wayne Norton
Authors: Joseph Wayne Norton (norton@alum.mit.edu
).
GEN_ETS is an generic wrapper for Erlang Term Storage with a callback interface for a backend implementation.
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
In particular, GEN_ETS differs from ETS in the following ways:
-
The name of a table can be any Erlang term.
-
All APIs require a namespace. A namespace must be a unique, reserved atom. Due to limitiations of the current implementation of GEN_ETS, this reserved atom is used to register a local named process and to create a named ets table.
Caution Choose your application's namespace(s) wisely.
For convience and testing purposes, GEN_ETS provides a default
namespace wrapper and backend implementation based on ETS. See
gen_ets
and gen_ets_impl_ets
for further details.
This repository is experimental in nature - use at your own risk and please contribute if you find GEN_ETS useful.
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
$ make deps clean compile
OR if QuickCheck is available then 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
$ make deps clean eqc
$ (cd .qc; erl -smp +A 5 -pz ../deps/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.
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.
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.
-
Configure your e-mail and name for Git
$ git config \--global user.email "you@example.com" $ git config \--global user.name "Your Name"
-
Install Repo
$ mkdir -p ~/bin $ wget -O - https://dl-ssl.google.com/dl/googlesource/git-repo/repo > ~/bin/repo $ chmod a+x ~/bin/repo
-
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. -
Download Git repositories
$ cd working-directory-name $ repo sync
For further information and help for related tools, please refer to the following links:
-
Erlang - http://www.erlang.org/
-
R15 or newer, R16B has been tested most recently
-
-
Git - http://git-scm.com/
-
Git 1.5.4 or newer, Git 1.8.2 has been tested most recently
-
required for Repo and GitHub
-
-
GitHub - https://github.com
-
Python - http://www.python.org
-
Python 2.4 or newer, Python 2.7.3 has been tested most recently (CAUTION: Python 3.x might be too new)
-
required for Repo
-
-
Get and install an erlang system http://www.erlang.org
-
Build
$ cd working-directory-name $ make compile
-
Dialyzer Testing basic recipe
-
Build Dialyzer's PLT (required once)
$ cd working-directory-name $ make build-plt
Tip Check Makefile and dialyzer's documentation for further information. -
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 .eunit directory. Check Makefile for further information. -
Dialyze without specs
$ cd working-directory-name $ make dialyze-nospec
-
-
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").
-
Compile for QuickCheck
$ cd working-directory-name $ make clean $ make compile-for-eqc
-
Run 5,000 QuickCheck tests
$ cd working-directory-name/deps/gen_ets/.qc $ 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)
.
-
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").
-
Compile for PropEr
$ cd working-directory-name $ make clean $ make compile-for-proper
-
Run 5,000 PropEr tests
$ cd working-directory-name/deps/gen_ets/.qc $ 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 .......
N/A
gen_ets |
gen_ets_impl_ets |
gen_ets_lib |
gen_ets_ns |
gen_ets_reg |