Not every time we want to pull data out of an erlang ETS table is it as straightfoward as the previous example. Sometimes we want to get all values that are greater than zero, rather than just constants. We’ll need to use the ets:select function, which has support for guards.
Here’s a basic setup.
Tmp = ets:new(tmp, []).
ets:insert(Tmp, {bob, 0}).
ets:insert(Tmp, {jim, 1}).
ets:insert(Tmp, {jon, 2}).% Returns all results
ets:select(Tmp,[{{'$1','$2'},[],['$$']}]).% Returns results where $2 > 0 (jim and jon)
ets:select(Tmp,[{ {'$1','$2'}, [ { '>', '$2', 0 } ],['$$'] }]).
What’s going on in the select? There’s a LOT of syntax for something that’s so simple, but once we break it up a bit it starts to be easier to look at.
First off, lets take a look at the original spec.
MatchSpec = [MatchFunction]
MatchFunction = {MatchHead, [Guard], [Result]}
MatchHead = “Pattern as in ets:match”
Guard = {“Guardtest name”, …}
Result = “Term construct”
Pretty important stuff in here. The basic building block of the MatchSpec is a list. Inside the list, is a “matchfunction”.
[MatchFunction]
Next, we break the MatchFunction up a little bit more. MatchHead = Pattern. We’ve seen this before.
MatchSpec = [ {Pattern, [Guard], [Result] } ]
Now, lets write our basic pattern. We want the rows where the 2nd item is > 0. So, since we can’t put that in the pattern yet, we’ll just give it a reference.
MatchSpec = [ { {$1, $2}, [Guard], [Result] } ]
OK, cool. That’s not so bad anymore! Next step – lets use our guard. There’s a funky syntax for guards in the matchspec, so here we go. You’re looking at a list, right? So it can have many items. Each item is a record. They can nest. We’ll ignore that for now. What we need to know here is that in a pattern matching guard, we put the operation first. It would normally read $2 > 0.
[ { '>', '$2', 0} ]
That’ll give us the pattern we want. What about the Result? Feel free to just use ‘$$’ in there. It’ll just kick back what you specified in your pattern. If you don’t believe me,
8> ets:select(Tmp,[{ {'_','$2'},[ { '>', '$2', 0 } ],['$$']}]).
[[1],[2]]
Put it all together!
ets:select(Tmp,[{ {'$1','$2'}, [ { '>', '$2', 0 } ], ['$$'] }]).
Not so bad anymore.
For testing purposes, you can use this bad boy.
test_ms(Tuple, MatchSpec)
You can also use this handy function to transform functions to selects:
fun2ms(LiteralFun) -> MatchSpec
One Response to Erlang: ETS Matching with Guards (select/2)
Leave a Reply Cancel reply
Recent Comments
- Anil on MySQL Triggers Tutorial
- Ashish on MySQL Triggers Tutorial
- David on iCal Agenda
- jon on IP address geolocation SQL database
- pim on IP address geolocation SQL database
- jnns on Redis Wildcard Delete
- K.C. Murphy on iCal Agenda
- BA on Experts Exchange should be removed from Google search results
- Andrew on Executing multiple curl requests in parallel with PHP and curl_multi_exec
- Stu on Executing multiple curl requests in parallel with PHP and curl_multi_exec
Recent Posts
- New Project: Jester
- Open New Terminal Tip
- Installing MySQLdb on MacOS Lion
- Headless VM Server Using Ubuntu 11.10
- Get rid of Facebook’s Awful Ticker
- Api Tester now hosted on Github
- Trac .11 jQuery bug
- Multiple Filetypes in Vim
- Git Tip: Setting Up Your Remote Server
- Install issue pymongo on OSX (setuptools out of date)
Categories
- amazon (1)
- answerbag (6)
- apache (9)
- apple (8)
- awk (2)
- bbedit (2)
- c++ (3)
- chrome (2)
- cluster (1)
- cocoa (1)
- collective intelligence (1)
- curl (3)
- db2 (1)
- demand media (1)
- ebay (1)
- eclipse (4)
- erlang (13)
- facebook (1)
- fortran (1)
- gen_server (1)
- git (5)
- google (4)
- haddad (1)
- hdf5 (1)
- html (1)
- innodb (1)
- itunes (1)
- java (2)
- jester (1)
- kvm (1)
- launchbar (1)
- leex (1)
- letsgetnuts.com (1)
- libvirt (1)
- links (6)
- linux (27)
- lucene (1)
- mac (16)
- memcached (1)
- misconception (1)
- mobile (1)
- mono (1)
- mssql (1)
- munin (1)
- mysql (31)
- numpy (1)
- oracle (1)
- php (23)
- puppet (4)
- pyparsing (1)
- pytables (1)
- python (11)
- q&a (1)
- quicksilver (1)
- rant (6)
- readynas (1)
- redis (2)
- regex (1)
- replication (1)
- search (1)
- shitty code (1)
- solr (3)
- spaces (1)
- sshfs (1)
- stored procedure (1)
- svn (5)
- textmate (2)
- tips (22)
- trac (1)
- tutorial (4)
- ubuntu (3)
- Uncategorized (4)
- unix (1)
- vim (3)
- virtual box (6)
- vmware (1)
- weird (3)
- wikipedia (1)
- windows (1)
- xcode (1)








Also check out the man page for ms_transform (in stdlib), here.
It allows you to write select patterns in a much nicer syntax. For your example:
Eshell V5.6.4 (abort with ^G)
1> ets:fun2ms(fun({_,X}=Obj) when X > 0 -> Obj end).
[{{'_','$1'},[{'>','$1',0}],['$_']}]