using mruby in a database
DESCRIPTION
TRANSCRIPT
Running MRuby in a database
Totally awesome, useful or just another pointless approach?
Frank Celler, triAGENS, CologneRuPy 2012, Brno
2012-11-16
www.arangodb.org (c) [email protected]
Samstag, 17. November 12
Agenda
NoSQL database ArangoDB
Use-Cases for actions
mruby
V8 or mruby?
www.arangodb.org (c) [email protected]
Samstag, 17. November 12
NoSQL Databases
Key/Value Store Document (Object) DB
Graph Database
www.arangodb.org (c) [email protected]
Samstag, 17. November 12
NoSQL Databases
Key/Value Store Document (Object) DB
Graph Database
www.arangodb.org (c) [email protected]
2012-11-11: 150 DB onnosql-databases.org
Samstag, 17. November 12
NoSQL Databases
Key/Value Store Document (Object) DB
Graph Database
www.arangodb.org (c) [email protected]
PolyglotPersistence
Multi-ModelDatabases
2012-11-11: 150 DB onnosql-databases.org
Samstag, 17. November 12
www.arangodb.org (c) [email protected]
Multi-Model Open-Source Database
Various Indexes: Skip-Lists, Hashes, Geo, Cap
Language API/Drivers for big Ps, Ruby, JS
Embedded JavaScript & Ruby engine
Written in C/C++
Query Language for Joins and Sub-Structures
Samstag, 17. November 12
www.arangodb.org (c) [email protected]
Query Language:FOR u in Users LET rs = ( FOR r in Recommendations FILTER r.rec_by == u._id && r.type == "Book" RETURN r.book_title ) FILTER length(rs) >= 3 RETURN { "name" : u.name, "titles" : rs }
(compare with UNQL / JSONiq)
FOR u IN users LET friends = ( FOR p in PATHS(user, relations, ``outbound´´, 1) FILTER p._from == u._id )RETURN { user: u, closeFriends: friends }
Samstag, 17. November 12
Use-Cases for script languages
GET /user/fceller
function (req, res) { var user = db.users.byExample({ username: req.urlParameters.username }); ... deal with unknown user...
user.age = ... compute user age from birthday ...; delete user.hashedPassword; actions.resultOk(req, res, actions.HTTP_OK, user);}
www.arangodb.org (c) [email protected]
enrich result
hide info
Samstag, 17. November 12
Use-Cases for script languages
GET /user/fceller/eccentricity
function (req, res) { var user = db.users.byExample({ username: req.urlParameters.username }); ... deal with unknown user...
var eccentricity = ... compute eccentricity ...; actions.resultOk(req, res, actions.HTTP_OK, eccentricity);}
www.arangodb.org (c) [email protected]
needs every node
Samstag, 17. November 12
Use-Cases for script languages
www.arangodb.org (c) [email protected]
Transactions
Triggers
Predefined Objects for AJAX
Samstag, 17. November 12
MRuby
Matz'sembeddable
minimal implementation of Ruby language
www.arangodb.org (c) [email protected]
Samstag, 17. November 12
MRuby
RiteVM as core
Minimal standard libraries
Embeddable C API
No perfect languages, even Ruby
Like to provide choices
www.arangodb.org (c) [email protected]
quotes from Matz
Samstag, 17. November 12
MRuby vs V8
JavaScript is a “complicated” language for embedding C++ class hierarchies
V8 itself is complex (isolates, contexts, handle scopes), but fast
mruby is plain and simple C code
documentation is sketchy for both
www.arangodb.org (c) [email protected]
Samstag, 17. November 12
MRuby vs V8
def fact n; (n > 1) ? n*fact(n-1) : 1; end
mruby: 20 time-units
V8: 0.6 time-units
php: 20 time-units
Ruby 1.9 (int): 9 time-units
www.arangodb.org (c) [email protected]
Samstag, 17. November 12
Why use MRuby?
“Like to provide choices”
i.e. if you don‘t like prototype inheritance
“still young”
i.e. instead of using RiteVM, compile to machine code
www.arangodb.org (c) [email protected]
Samstag, 17. November 12
MRuby and LLVM
www.arangodb.org (c) [email protected]
000 OP_ENTER 1:0:0:0:0:0:0001 OP_MOVE R4 R1002 OP_LOADI R5 1003 OP_LOADNIL R6004 OP_GT R4 '>' 1005 OP_JMPNOT R4 017006 OP_MOVE R4 R1007 OP_LOADSELF R5008 OP_MOVE R6 R1009 OP_LOADI R7 1010 OP_LOADNIL R8011 OP_SUB R6 '-' 1012 OP_LOADNIL R7013 OP_SEND R5 'fact' 1014 OP_LOADNIL R6 015 OP_MUL R4 '*' 1016 OP_JMP 018017 OP_LOADI R4 1018 OP_RETURN R4
def fact n; (n > 1) ? n*fact(n-1) : 1; end
Samstag, 17. November 12
MRuby and LLVM
www.arangodb.org (c) [email protected]
CASE(OP_SUB) { /* A B C R(A) := R(A)-R(A+1) (Syms[B]=:-,C=1)*/ int a = GETARG_A(i);
/* need to check if op is overridden */ switch (TYPES2(mrb_type(regs[a]),mrb_type(regs[a+1]))) { case TYPES2(MRB_TT_FIXNUM,MRB_TT_FIXNUM): { mrb_int x, y, z;
x = mrb_fixnum(regs[a]); y = mrb_fixnum(regs[a+1]); z = x - y; if (((x < 0) ^ (y < 0)) == 0 && (x < 0) != (z < 0)) { /* integer overflow */ SET_FLT_VALUE(regs[a], (mrb_float)x - (mrb_float)y); break; } SET_INT_VALUE(regs[a], z); } break;
Simply replacing OP codes by machine code already gives a factor of 2
Samstag, 17. November 12
Why use MRuby?
If you have use-cases for scripts in ArangoDB (or any other database), mruby will eventually be an alternative
Otherwise, use a language driver (aka Ashikawa for Ruby) and CRuby or JRuby
www.arangodb.org (c) [email protected]
Samstag, 17. November 12
Thank You!
Fork me on github
Google Group: ArangoDB
Twitter: @fceller & @arangodb
www.arangodb.org
www.arangodb.org (c) [email protected]
Stay in Touch:
Samstag, 17. November 12