Skip to content

Latest commit

 

History

History
693 lines (579 loc) · 11.9 KB

README.md

File metadata and controls

693 lines (579 loc) · 11.9 KB

#GEN_ETS - GEN(eric) Erlang Term Storage#

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.

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
$ 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.

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 further information and help for related tools, please refer to the following links:

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

  1. 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 .eunit 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 compile-for-eqc
  3. 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, tryqc_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 compile-for-proper
  3. 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
    .......

Roadmap

N/A

##Modules##

gen_ets
gen_ets_impl_ets
gen_ets_lib
gen_ets_ns
gen_ets_reg