SlideShare ist ein Scribd-Unternehmen logo
1 von 152
Downloaden Sie, um offline zu lesen
node-ffi
othree jsdc
@othree
othree.net MozTW
F2E at HTC PhD Candidate
Topics
r3 ffi
node-ffi
node-ffi
packages
node-r3
r3
https://github.com/c9s/r3
r3
http://c9s.blogspot.tw/2014/05/r3-url-router-library.html
How to Use libr3
Sample 1/2
n = r3_tree_create(10);!
!
int route_data = 3;!
!
r3_tree_insert_routel(n, METHOD_GET, "/blog/post", !
sizeof("/blog/post") - 1, &route_data );!
!
int err = r3_tree_compile(n, &errstr);
Sample 1/2
n = r3_tree_create(10);!
!
int route_data = 3;!
!
r3_tree_insert_routel(n, METHOD_GET, "/blog/post", !
sizeof("/blog/post") - 1, &route_data );!
!
int err = r3_tree_compile(n, &errstr);
Create Tree
Sample 1/2
n = r3_tree_create(10);!
!
int route_data = 3;!
!
r3_tree_insert_routel(n, METHOD_GET, "/blog/post", !
sizeof("/blog/post") - 1, &route_data );!
!
int err = r3_tree_compile(n, &errstr);
Insert Route
Sample 1/2
n = r3_tree_create(10);!
!
int route_data = 3;!
!
r3_tree_insert_routel(n, METHOD_GET, "/blog/post", !
sizeof("/blog/post") - 1, &route_data );!
!
int err = r3_tree_compile(n, &errstr);
Data
Sample 1/2
n = r3_tree_create(10);!
!
int route_data = 3;!
!
r3_tree_insert_routel(n, METHOD_GET, "/blog/post", !
sizeof("/blog/post") - 1, &route_data );!
!
int err = r3_tree_compile(n, &errstr);
Compile
node ffi
Sample 2/2
match_entry * entry = match_entry_create("/blog/post");!
entry->request_method = METHOD_GET;!
!
route *matched_route = r3_tree_match_route(n, entry);!
matched_route->data; // The Data!
!
match_entry_free(entry);!
r3_tree_free(n);
Sample 2/2
match_entry * entry = match_entry_create("/blog/post");!
entry->request_method = METHOD_GET;!
!
route *matched_route = r3_tree_match_route(n, entry);!
matched_route->data; // The Data!
!
match_entry_free(entry);!
r3_tree_free(n);
Create Entry
Sample 2/2
match_entry * entry = match_entry_create("/blog/post");!
entry->request_method = METHOD_GET;!
!
route *matched_route = r3_tree_match_route(n, entry);!
matched_route->data; // The Data!
!
match_entry_free(entry);!
r3_tree_free(n);
Match Route
Sample 2/2
match_entry * entry = match_entry_create("/blog/post");!
entry->request_method = METHOD_GET;!
!
route *matched_route = r3_tree_match_route(n, entry);!
matched_route->data; // The Data!
!
match_entry_free(entry);!
r3_tree_free(n);
Route Data
match_entry
Captures
{variable_name}!
node ffi
Sample 2/2
match_entry * entry = match_entry_create(“/blog/post/1/2/3“);!
entry->request_method = METHOD_GET; // Method Condition!
!
route *matched_route = r3_tree_match_route(n, entry);!
!
matched_route->data; // The Data!
entry->vars; //Captured Vars, a string array!
!
r3_tree_free(n);
May I Use r3 in node
Yes.
How?
How
Why
Foreign Function
Interface
https://en.wikipedia.org/wiki/Foreign_function_interface
node ffi
__cdecl
val = sumExample(2,3)
; // push arguments to the stack, from right to left!
push 3 !
push 2 !
!
; // call the function!
call _sumExample !
!
; // cleanup the stack by adding the size of the arguments to!
; // ESP register!
add esp,8 !
!
; // copy the return value from EAX to a local variable (int c)!
mov dword ptr [c],eax
node-ffi
https://github.com/node-ffi/node-ffi
So node-ffi Knows
node ffi
@TooTallNate
ffi Packages
ffi ref
ref-struct ref-array
ffi Foreign Function Call
ref Reference Tools
ref-struct Struct Helper
ref-array Array Helper
Example
var ffi = require('ffi');!
!
var libm = ffi.Library('libm', {!
'ceil': [ 'double', [ 'double' ] ]!
});!
!
libm.ceil(1.5); // 2
Example
var ffi = require('ffi');!
!
var libm = ffi.Library('libm', {!
'ceil': [ 'double', [ 'double' ] ]!
});!
!
libm.ceil(1.5); // 2
Library name!
Use dlopen
Example
var ffi = require('ffi');!
!
var libm = ffi.Library('libm', {!
'ceil': [ 'double', [ 'double' ] ]!
});!
!
libm.ceil(1.5); // 2
A function named ‘ceil’ return double

Take one double parameter
Example
var ffi = require('ffi');!
!
var libm = ffi.Library('libm', {!
'ceil': [ 'double', [ 'double' ] ]!
});!
!
libm.ceil(1.5); // 2
return type
Example
var ffi = require('ffi');!
!
var libm = ffi.Library('libm', {!
'ceil': [ 'double', [ 'double' ] ]!
});!
!
libm.ceil(1.5); // 2
arguments type
Types
void bool byte pointer
(u)short (u)int (u)int16 (u)int32
(u)int64 (u)longlong size_t float
(u)char string object
Example
var ffi = require('ffi');!
!
var libm = ffi.Library('libm', {!
'ceil': [ 'double', [ 'double' ] ]!
});!
!
libm.ceil(1.5); // 2
Call ceil
To Use node-ffi
ffi.Library
math.h
http://www.cplusplus.com/reference/cmath/ceil/
double ceil (double x);
var libm = ffi.Library('libm', {!
'ceil': [ 'double', [ 'double' ] ]!
});
math.h
http://www.cplusplus.com/reference/cmath/ceil/
double ceil (double x);
var libm = ffi.Library('libm', {!
'ceil': [ 'double', [ 'double' ] ]!
});
math.h
http://www.cplusplus.com/reference/cmath/ceil/
double ceil (double x);
var libm = ffi.Library('libm', {!
'ceil': [ 'double', [ 'double' ] ]!
});
math.h
http://www.cplusplus.com/reference/cmath/ceil/
double ceil (double x);
var libm = ffi.Library('libm', {!
'ceil': [ 'double', [ 'double' ] ]!
});
r3.h
node ffi
node ffi
Struct?
Struct
struct _edge {!
char * pattern; // 8 bytes!
node * child; // 8 bytes!
unsigned char pattern_len; // 1 byte!
unsigned char opcode:4; // 4 bit!
unsigned char has_slug:1; // 1 bit!
};
var StructType = require('ref-struct');!
!
var edge = StructType({!
pattern: "string",!
child: "pointer",!
pattern_len: "ushort",!
opcode: "uchar",!
has_slug: "uchar"!
});
ref-struct
https://en.wikipedia.org/wiki/Application_binary_interface
https://mentorembedded.github.io/cxx-abi/abi.html
https://mentorembedded.github.io/cxx-abi/
Struct in Struct?
typedef struct {!
str_array * vars;!
const char * path; // current path to dispatch!
int path_len; // the length of the current path!
int request_method; // current request method!
void * data; // route ptr!
char * host; // the request host!
!
...
typedef struct {!
str_array * vars;!
const char * path; // current path to dispatch!
int path_len; // the length of the current path!
int request_method; // current request method!
void * data; // route ptr!
char * host; // the request host!
!
...
var ref = require('ref');!
!
var str_array = StructType({ ... });!
!
var match_entry = StructType({!
vars: ref.refType(str_array),!
path: "string",!
path_len: "int",!
request_method: "int",!
data: "pointer",!
host: "pointer",!
...
https://tootallnate.github.io/ref/
node ffi
ref.refType
https://tootallnate.github.io/ref/
ref.refType
indirection *
ref.refType
StructType({!
var1: str_array,!
var2: ref.refType(str_array)!
});
str_array var1;!
str_array * var2;
ref.refType
StructType({!
var1: str_array,!
var2: ref.refType(str_array)!
});
str_array var1;!
str_array * var2;
ref.refType
StructType({!
var1: str_array,!
var2: ref.refType(str_array)!
});
str_array var1;!
str_array * var2;
ref.refType
StructType({!
var1: str_array,!
var2: ref.refType(str_array),!
var3: ref.refType(ref.refType(str_array)),!
});
str_array var1;!
str_array * var2;!
str_array **var3;
Back to r3.h
node ffi
node ffi
#define
#define r3_tree_insert_path(n,p,d) r3_tree_insert_pathl_ex(n,p,s
var libr3 = ffi.Library('libr3', {!
"r3_tree_insert_pathl_ex": ["pointer", ["pointer", "string", "
});!
!
!
var r3_tree_insert_path = function (tree, path, data) {!
return libr3.r3_tree_insert_pathl_ex(tree, path, path.length,
};
r3.h
r3.h
node-ffi-generate
https://github.com/tjfontaine/node-ffi-generate
node-r3
Now We Can Write
ffi.Library Define for r3
node ffi
node ffi
Route Data
route * r3_tree_insert_routel(node *tree, int method,

const char *path, int path_len, void *data);
route * r3_tree_insert_routel(node *tree, int method,

const char *path, int path_len, void *data);
Route Data
Pointer?
Pointer in JS
Buffer
Example 1/2
var tree = libr3.r3_tree_create(10);!
!
var data = new Buffer(data_str + 'u0000');!
!
r3_tree_insert_route(tree, 'GET','/path', data);
Example 2/2
var node = libr3.r3_tree_match_route(tree, entry);!
!
var data = ref.deref(node).data;
https://github.com/othree/node-r3/blob/46e29f72bbf68097ed66fd151f9ef42d5a3ede05/node-r3.js
ref.deref


The Data
BUT
The Problem
data
data
Solution 1
• buffer.type!
• ref.reinterpret
ref.reinterpret
Cons
Solution 2
ref.readCString
ref.readCString
00
var data = new Buffer(data_str + 'u0000');
var data = ref.readCString(ref.deref(node).data, 0);
Cons
node ffi
Performance
Spec
https://github.com/c9s/r3/blob/master/tests/bench.c
Route req/s
director ~2200
node-r3 0.0.1 ~1900


What Takes Time
Transform String
data = new Buffer(data + 'u0000');!
r3_tree_insert_path(this.tree, route, data);
var node = r3_tree_match(this.tree, path, entry);!
!
var data = ref.readCString(node.deref().data, 0);
How to Skip Transform
var i = this.i++;!
this.data[i] = data;!
!
var iref = ref.alloc('int', i);!
!
libr3.r3_tree_insert_route(this.tree, method, route, iref);
var node = libr3.r3_tree_match_route(this.tree, entry);!
!
var index = node.deref().data.reinterpret(4).readUInt32LE(0);!
!
var data = this.data[index];
var i = this.i++;!
this.data[i] = data;!
!
var iref = ref.alloc('int', i);!
!
libr3.r3_tree_insert_route(this.tree, method, route, iref);
var node = libr3.r3_tree_match_route(this.tree, entry);!
!
var index = node.deref().data.reinterpret(4).readUInt32LE(0);!
!
var data = this.data[index];
Store Data
ref.alloc
var i = this.i++;!
this.data[i] = data;!
!
var iref = ref.alloc('int', i);!
!
libr3.r3_tree_insert_route(this.tree, method, route, iref);
var node = libr3.r3_tree_match_route(this.tree, entry);!
!
var index = node.deref().data.reinterpret(4).readUInt32LE(0);!
!
var data = this.data[index];
Data for r3
var i = this.i++;!
this.data[i] = data;!
!
var iref = ref.alloc('int', i);!
!
libr3.r3_tree_insert_route(this.tree, method, route, iref);
var node = libr3.r3_tree_match_route(this.tree, entry);!
!
var index = node.deref().data.reinterpret(4).readUInt32LE(0);!
!
var data = this.data[index];
Resize Buffer
var i = this.i++;!
this.data[i] = data;!
!
var iref = ref.alloc('int', i);!
!
libr3.r3_tree_insert_route(this.tree, method, route, iref);
var node = libr3.r3_tree_match_route(this.tree, entry);!
!
var index = node.deref().data.reinterpret(4).readUInt32LE(0);!
!
var data = this.data[index];
Read Index
readUInt32LE
Route req/s
director ~2200
node-r3 0.0.1 ~1900
node-r3 0.0.3 ~5000
More Pros
How About Foreign Calls
What is Omissible
match_entry_create match_entry_free
So
Route req/s
director ~2200
node-r3 0.0.1 ~1900
node-r3 0.0.3 ~5000
node-r3 0.1.0 7800~10600 Not Yet
node ffi
Crash…
node ffi
node ffi
Hard To Find The Bug
var Router = function (routes) {!
var route, data, method, route_frag, i = 0;!
this.tree = libr3.r3_tree_create(10);!
this.data = [];!
for (route in routes) {!
this.data[i] = routes[route];!
data = ref.alloc('int', i);!
route = route.trim();!
route_frag = route.split(' ');!
if (route_frag.length > 1) {!
route = route_frag[1];!
method = METHODS[route_frag[0].toUpperCase()];!
if (!method) { throw new Error(route_frag[0]); }!
r3_tree_insert_route(this.tree, method, route, data);!
} else {!
r3_tree_insert_route(this.tree, 0, route, data);!
}!
i++;!
}!
libr3.r3_tree_compile(this.tree);!
return this;!
};
var Router = function (routes) {!
var route, data, method, route_frag, i = 0;!
this.tree = libr3.r3_tree_create(10);!
this.data = [];!
for (route in routes) {!
this.data[i] = routes[route];!
data = ref.alloc('int', i);!
route = route.trim();!
route_frag = route.split(' ');!
if (route_frag.length > 1) {!
route = route_frag[1];!
method = METHODS[route_frag[0].toUpperCa
if (!method) { throw new Error(route_fra
r3_tree_insert_route(this.tree, method,
} else {!
r3_tree_insert_route(this.tree, 0, route
}!
i++;!
}!
libr3.r3_tree_compile(this.tree);!
return this;!
};
var Router = function (routes) {!
var route, data, method, route_frag, i = 0;!
this.tree = libr3.r3_tree_create(10);!
this.data = [];!
for (route in routes) {!
this.data[i] = routes[route];!
data = ref.alloc('int', i);!
route = route.trim();!
route_frag = route.split(' ');!
if (route_frag.length > 1) {!
route = route_frag[1];!
method = METHODS[route_frag[0].toUpperCa
if (!method) { throw new Error(route_fra
r3_tree_insert_route(this.tree, method,
} else {!
r3_tree_insert_route(this.tree, 0, route
}!
i++;!
}!
libr3.r3_tree_compile(this.tree);!
return this;!
};
var Router = function (routes) {!
var route, data, method, route_frag, i = 0;!
this.tree = libr3.r3_tree_create(10);!
this.data = [];!
for (route in routes) {!
this.data[i] = routes[route];!
data = ref.alloc('int', i);!
route = route.trim();!
route_frag = route.split(' ');!
if (route_frag.length > 1) {!
route = route_frag[1];!
method = METHODS[route_frag[0].toUpperCa
if (!method) { throw new Error(route_fra
r3_tree_insert_route(this.tree, method,
} else {!
r3_tree_insert_route(this.tree, 0, route
}!
i++;!
}!
libr3.r3_tree_compile(this.tree);!
return this;!
};
var Router = function (routes) {!
var route, data, method, route_frag, i = 0;!
this.tree = libr3.r3_tree_create(10);!
this.data = [];!
for (route in routes) {!
this.data[i] = routes[route];!
data = ref.alloc('int', i);!
route = route.trim();!
route_frag = route.split(' ');!
if (route_frag.length > 1) {!
route = route_frag[1];!
method = METHODS[route_frag[0].toUpperCa
if (!method) { throw new Error(route_fra
r3_tree_insert_route(this.tree, method,
} else {!
r3_tree_insert_route(this.tree, 0, route
}!
i++;!
}!
libr3.r3_tree_compile(this.tree);!
return this;!
};
var Router = function (routes) {!
var route, data, method, route_frag, i = 0;!
this.tree = libr3.r3_tree_create(10);!
this.data = [];!
for (route in routes) {!
this.data[i] = routes[route];!
data = ref.alloc('int', i);!
route = route.trim();!
route_frag = route.split(' ');!
if (route_frag.length > 1) {!
route = route_frag[1];!
method = METHODS[route_frag[0].toUpperCa
if (!method) { throw new Error(route_fra
r3_tree_insert_route(this.tree, method,
} else {!
r3_tree_insert_route(this.tree, 0, route
}!
i++;!
}!
libr3.r3_tree_compile(this.tree);!
return this;!
};
var Router = function (routes) {!
var route, data, method, route_frag, i = 0;!
this.tree = libr3.r3_tree_create(10);!
this.data = [];!
for (route in routes) {!
this.data[i] = routes[route];!
data = ref.alloc('int', i);!
route = route.trim();!
route_frag = route.split(' ');!
if (route_frag.length > 1) {!
route = route_frag[1];!
method = METHODS[route_frag[0].toUpperCa
if (!method) { throw new Error(route_fra
r3_tree_insert_route(this.tree, method,
} else {!
r3_tree_insert_route(this.tree, 0, route
}!
i++;!
}!
libr3.r3_tree_compile(this.tree);!
return this;!
};
var Router = function (routes) {!
var route, data, method, route_frag, i = 0;!
this.tree = libr3.r3_tree_create(10);!
this.data = [];!
for (route in routes) {!
this.data[i] = routes[route];!
data = ref.alloc('int', i);!
route = route.trim();!
route_frag = route.split(' ');!
if (route_frag.length > 1) {!
route = route_frag[1];!
method = METHODS[route_frag[0].toUpperCa
if (!method) { throw new Error(route_fra
r3_tree_insert_route(this.tree, method,
} else {!
r3_tree_insert_route(this.tree, 0, route
}!
i++;!
}!
libr3.r3_tree_compile(this.tree);!
return this;!
};
var Router = function (routes) {!
var route, data, method, route_frag, i = 0;!
this.tree = libr3.r3_tree_create(10);!
this.data = [];!
for (route in routes) {!
this.data[i] = routes[route];!
data = ref.alloc('int', i);!
route = route.trim();!
route_frag = route.split(' ');!
if (route_frag.length > 1) {!
route = route_frag[1];!
method = METHODS[route_frag[0].toUpperCa
if (!method) { throw new Error(route_fra
r3_tree_insert_route(this.tree, method,
} else {!
r3_tree_insert_route(this.tree, 0, route
}!
i++;!
}!
libr3.r3_tree_compile(this.tree);!
return this;!
};
var Router = function (routes) {!
var route, data, method, route_frag, i = 0;!
this.tree = libr3.r3_tree_create(10);!
this.data = [];!
for (route in routes) {!
this.data[i] = routes[route];!
data = ref.alloc('int', i);!
route = route.trim();!
route_frag = route.split(' ');!
if (route_frag.length > 1) {!
route = route_frag[1];!
method = METHODS[route_frag[0].toUpperCa
if (!method) { throw new Error(route_fra
r3_tree_insert_route(this.tree, method,
} else {!
r3_tree_insert_route(this.tree, 0, route
}!
i++;!
}!
libr3.r3_tree_compile(this.tree);!
return this;!
};
Any Idea?
var Router = function (routes) {!
var route, data, method, route_frag, i = 0;!
this.tree = libr3.r3_tree_create(10);!
this.data = [];!
for (route in routes) {!
this.data[i] = routes[route];!
data = ref.alloc('int', i);!
route = route.trim();!
route_frag = route.split(' ');!
if (route_frag.length > 1) {!
route = route_frag[1];!
method = METHODS[route_frag[0].toUpperCase()];!
if (!method) { throw new Error(route_frag[0]); }!
r3_tree_insert_route(this.tree, method, route, data);!
} else {!
r3_tree_insert_route(this.tree, 0, route, data);!
}!
i++;!
}!
libr3.r3_tree_compile(this.tree);!
return this;!
};
The Bug
data
var Router = function (routes) {!
var route, data, method, route_frag, i = 0;!
this.tree = libr3.r3_tree_create(10);!
this.data = [];!
this.index = [];!
for (route in routes) {!
this.data[i] = routes[route];!
data = ref.alloc('int', i);!
this.index[i] = data; // prevent GC!
route = route.trim();!
route_frag = route.split(' ');!
if (route_frag.length > 1) {!
route = route_frag[1];!
method = METHODS[route_frag[0].toUpperCase()];!
if (!method) { throw new Error(route_frag[0]); }!
r3_tree_insert_route(this.tree, method, route, data);!
} else {!
r3_tree_insert_route(this.tree, 0, route, data);!
}!
i++;!
}!
libr3.r3_tree_compile(this.tree);!
return this;!
};
node ffi
node ffi
node-r3
var Router = require('node-r3').Router;!
!
var router = new Router({!
"/foo": "data string",!
"/foo/bar": function () {},!
"/foo/bar/qoo": {obj: 1},!
});!
!
var dispatched = router.match("/foo");!
!
router.free();
var router = new Router({!
"/": handler,!
"/foo": fooHandler,!
"/foo/{id}": fooHandler,!
"POST /me": postMeHandler,!
"GET /me": getMeHandler,!
"POST|GET /post": postHandler,!
});!
!
var server = http.createServer(!
router.httpHandler(notfound)!
);
Handler Function
function (req, res, captures)
array
Error Handler Function
function (req, res)
Known Issues
Question?
Thanks For your
Attention

Weitere ähnliche Inhalte

Was ist angesagt?

Explaining ES6: JavaScript History and What is to Come
Explaining ES6: JavaScript History and What is to ComeExplaining ES6: JavaScript History and What is to Come
Explaining ES6: JavaScript History and What is to ComeCory Forsyth
 
What's New in ES6 for Web Devs
What's New in ES6 for Web DevsWhat's New in ES6 for Web Devs
What's New in ES6 for Web DevsRami Sayar
 
Interceptors: Into the Core of Pedestal
Interceptors: Into the Core of PedestalInterceptors: Into the Core of Pedestal
Interceptors: Into the Core of PedestalKent Ohashi
 
Lightweight wrapper for Hive on Amazon EMR
Lightweight wrapper for Hive on Amazon EMRLightweight wrapper for Hive on Amazon EMR
Lightweight wrapper for Hive on Amazon EMRShinji Tanaka
 
Python meetup: coroutines, event loops, and non-blocking I/O
Python meetup: coroutines, event loops, and non-blocking I/OPython meetup: coroutines, event loops, and non-blocking I/O
Python meetup: coroutines, event loops, and non-blocking I/OBuzzcapture
 
EcmaScript 6 - The future is here
EcmaScript 6 - The future is hereEcmaScript 6 - The future is here
EcmaScript 6 - The future is hereSebastiano Armeli
 
JavaScript - new features in ECMAScript 6
JavaScript - new features in ECMAScript 6JavaScript - new features in ECMAScript 6
JavaScript - new features in ECMAScript 6Solution4Future
 
Python Coroutines, Present and Future
Python Coroutines, Present and FuturePython Coroutines, Present and Future
Python Coroutines, Present and Futureemptysquare
 
Introduction to Ecmascript - ES6
Introduction to Ecmascript - ES6Introduction to Ecmascript - ES6
Introduction to Ecmascript - ES6Nilesh Jayanandana
 
JRuby @ Boulder Ruby
JRuby @ Boulder RubyJRuby @ Boulder Ruby
JRuby @ Boulder RubyNick Sieger
 
Nick Sieger JRuby Concurrency EMRubyConf 2011
Nick Sieger JRuby Concurrency EMRubyConf 2011Nick Sieger JRuby Concurrency EMRubyConf 2011
Nick Sieger JRuby Concurrency EMRubyConf 2011Nick Sieger
 
Go Concurrency
Go ConcurrencyGo Concurrency
Go Concurrencyjgrahamc
 
A deep dive into PEP-3156 and the new asyncio module
A deep dive into PEP-3156 and the new asyncio moduleA deep dive into PEP-3156 and the new asyncio module
A deep dive into PEP-3156 and the new asyncio moduleSaúl Ibarra Corretgé
 
Riga Dev Day 2016 - Having fun with Javassist
Riga Dev Day 2016 - Having fun with JavassistRiga Dev Day 2016 - Having fun with Javassist
Riga Dev Day 2016 - Having fun with JavassistAnton Arhipov
 
History & Practices for UniRx(EN)
History & Practices for UniRx(EN)History & Practices for UniRx(EN)
History & Practices for UniRx(EN)Yoshifumi Kawai
 
Working with databases in Perl
Working with databases in PerlWorking with databases in Perl
Working with databases in PerlLaurent Dami
 

Was ist angesagt? (20)

Explaining ES6: JavaScript History and What is to Come
Explaining ES6: JavaScript History and What is to ComeExplaining ES6: JavaScript History and What is to Come
Explaining ES6: JavaScript History and What is to Come
 
What's New in ES6 for Web Devs
What's New in ES6 for Web DevsWhat's New in ES6 for Web Devs
What's New in ES6 for Web Devs
 
Interceptors: Into the Core of Pedestal
Interceptors: Into the Core of PedestalInterceptors: Into the Core of Pedestal
Interceptors: Into the Core of Pedestal
 
Lightweight wrapper for Hive on Amazon EMR
Lightweight wrapper for Hive on Amazon EMRLightweight wrapper for Hive on Amazon EMR
Lightweight wrapper for Hive on Amazon EMR
 
Go Memory
Go MemoryGo Memory
Go Memory
 
Python meetup: coroutines, event loops, and non-blocking I/O
Python meetup: coroutines, event loops, and non-blocking I/OPython meetup: coroutines, event loops, and non-blocking I/O
Python meetup: coroutines, event loops, and non-blocking I/O
 
EcmaScript 6 - The future is here
EcmaScript 6 - The future is hereEcmaScript 6 - The future is here
EcmaScript 6 - The future is here
 
JavaScript - new features in ECMAScript 6
JavaScript - new features in ECMAScript 6JavaScript - new features in ECMAScript 6
JavaScript - new features in ECMAScript 6
 
Python Coroutines, Present and Future
Python Coroutines, Present and FuturePython Coroutines, Present and Future
Python Coroutines, Present and Future
 
Introduction to Ecmascript - ES6
Introduction to Ecmascript - ES6Introduction to Ecmascript - ES6
Introduction to Ecmascript - ES6
 
iSoligorsk #3 2013
iSoligorsk #3 2013iSoligorsk #3 2013
iSoligorsk #3 2013
 
JRuby @ Boulder Ruby
JRuby @ Boulder RubyJRuby @ Boulder Ruby
JRuby @ Boulder Ruby
 
Nick Sieger JRuby Concurrency EMRubyConf 2011
Nick Sieger JRuby Concurrency EMRubyConf 2011Nick Sieger JRuby Concurrency EMRubyConf 2011
Nick Sieger JRuby Concurrency EMRubyConf 2011
 
Go Concurrency
Go ConcurrencyGo Concurrency
Go Concurrency
 
A deep dive into PEP-3156 and the new asyncio module
A deep dive into PEP-3156 and the new asyncio moduleA deep dive into PEP-3156 and the new asyncio module
A deep dive into PEP-3156 and the new asyncio module
 
Riga Dev Day 2016 - Having fun with Javassist
Riga Dev Day 2016 - Having fun with JavassistRiga Dev Day 2016 - Having fun with Javassist
Riga Dev Day 2016 - Having fun with Javassist
 
Docopt
DocoptDocopt
Docopt
 
Ggug spock
Ggug spockGgug spock
Ggug spock
 
History & Practices for UniRx(EN)
History & Practices for UniRx(EN)History & Practices for UniRx(EN)
History & Practices for UniRx(EN)
 
Working with databases in Perl
Working with databases in PerlWorking with databases in Perl
Working with databases in Perl
 

Ähnlich wie node ffi

TYPO3 Extension development using new Extbase framework
TYPO3 Extension development using new Extbase frameworkTYPO3 Extension development using new Extbase framework
TYPO3 Extension development using new Extbase frameworkChristian Trabold
 
Functions And Header Files In C++ | Bjarne stroustrup
Functions And Header Files In C++ | Bjarne stroustrupFunctions And Header Files In C++ | Bjarne stroustrup
Functions And Header Files In C++ | Bjarne stroustrupSyedHaroonShah4
 
How to use Parquet as a basis for ETL and analytics
How to use Parquet as a basis for ETL and analyticsHow to use Parquet as a basis for ETL and analytics
How to use Parquet as a basis for ETL and analyticsJulien Le Dem
 
Puppet Camp Paris 2015: Power of Puppet 4 (Beginner)
Puppet Camp Paris 2015: Power of Puppet 4 (Beginner) Puppet Camp Paris 2015: Power of Puppet 4 (Beginner)
Puppet Camp Paris 2015: Power of Puppet 4 (Beginner) Puppet
 
Ruby on Rails: Tasty Burgers
Ruby on Rails: Tasty BurgersRuby on Rails: Tasty Burgers
Ruby on Rails: Tasty BurgersAaron Patterson
 
Php Extensions for Dummies
Php Extensions for DummiesPhp Extensions for Dummies
Php Extensions for DummiesElizabeth Smith
 
Introduction to source{d} Engine and source{d} Lookout
Introduction to source{d} Engine and source{d} Lookout Introduction to source{d} Engine and source{d} Lookout
Introduction to source{d} Engine and source{d} Lookout source{d}
 
AWS Hadoop and PIG and overview
AWS Hadoop and PIG and overviewAWS Hadoop and PIG and overview
AWS Hadoop and PIG and overviewDan Morrill
 
SQLite Techniques
SQLite TechniquesSQLite Techniques
SQLite Techniquesjoaopmaia
 
Create your own PHP extension, step by step - phpDay 2012 Verona
Create your own PHP extension, step by step - phpDay 2012 VeronaCreate your own PHP extension, step by step - phpDay 2012 Verona
Create your own PHP extension, step by step - phpDay 2012 VeronaPatrick Allaert
 
Node Boot Camp
Node Boot CampNode Boot Camp
Node Boot CampTroy Miles
 
Network security Lab manual
Network security Lab manual Network security Lab manual
Network security Lab manual Vivek Kumar Sinha
 
ECMAScript2015
ECMAScript2015ECMAScript2015
ECMAScript2015qmmr
 
Static types on javascript?! Type checking approaches to ensure healthy appli...
Static types on javascript?! Type checking approaches to ensure healthy appli...Static types on javascript?! Type checking approaches to ensure healthy appli...
Static types on javascript?! Type checking approaches to ensure healthy appli...Arthur Puthin
 
Architecture | Busy Java Developers Guide to NoSQL | Ted Neward
Architecture | Busy Java Developers Guide to NoSQL | Ted NewardArchitecture | Busy Java Developers Guide to NoSQL | Ted Neward
Architecture | Busy Java Developers Guide to NoSQL | Ted NewardJAX London
 

Ähnlich wie node ffi (20)

TYPO3 Extension development using new Extbase framework
TYPO3 Extension development using new Extbase frameworkTYPO3 Extension development using new Extbase framework
TYPO3 Extension development using new Extbase framework
 
Having Fun Programming!
Having Fun Programming!Having Fun Programming!
Having Fun Programming!
 
Functions And Header Files In C++ | Bjarne stroustrup
Functions And Header Files In C++ | Bjarne stroustrupFunctions And Header Files In C++ | Bjarne stroustrup
Functions And Header Files In C++ | Bjarne stroustrup
 
How to use Parquet as a basis for ETL and analytics
How to use Parquet as a basis for ETL and analyticsHow to use Parquet as a basis for ETL and analytics
How to use Parquet as a basis for ETL and analytics
 
Puppet Camp Paris 2015: Power of Puppet 4 (Beginner)
Puppet Camp Paris 2015: Power of Puppet 4 (Beginner) Puppet Camp Paris 2015: Power of Puppet 4 (Beginner)
Puppet Camp Paris 2015: Power of Puppet 4 (Beginner)
 
Php extensions
Php extensionsPhp extensions
Php extensions
 
Ruby on Rails: Tasty Burgers
Ruby on Rails: Tasty BurgersRuby on Rails: Tasty Burgers
Ruby on Rails: Tasty Burgers
 
Php Extensions for Dummies
Php Extensions for DummiesPhp Extensions for Dummies
Php Extensions for Dummies
 
Introduction to source{d} Engine and source{d} Lookout
Introduction to source{d} Engine and source{d} Lookout Introduction to source{d} Engine and source{d} Lookout
Introduction to source{d} Engine and source{d} Lookout
 
AWS Hadoop and PIG and overview
AWS Hadoop and PIG and overviewAWS Hadoop and PIG and overview
AWS Hadoop and PIG and overview
 
SQLite Techniques
SQLite TechniquesSQLite Techniques
SQLite Techniques
 
SQLite Techniques
SQLite TechniquesSQLite Techniques
SQLite Techniques
 
Create your own PHP extension, step by step - phpDay 2012 Verona
Create your own PHP extension, step by step - phpDay 2012 VeronaCreate your own PHP extension, step by step - phpDay 2012 Verona
Create your own PHP extension, step by step - phpDay 2012 Verona
 
Node Boot Camp
Node Boot CampNode Boot Camp
Node Boot Camp
 
Gcrc talk
Gcrc talkGcrc talk
Gcrc talk
 
Network security Lab manual
Network security Lab manual Network security Lab manual
Network security Lab manual
 
ECMAScript2015
ECMAScript2015ECMAScript2015
ECMAScript2015
 
Static types on javascript?! Type checking approaches to ensure healthy appli...
Static types on javascript?! Type checking approaches to ensure healthy appli...Static types on javascript?! Type checking approaches to ensure healthy appli...
Static types on javascript?! Type checking approaches to ensure healthy appli...
 
Architecture | Busy Java Developers Guide to NoSQL | Ted Neward
Architecture | Busy Java Developers Guide to NoSQL | Ted NewardArchitecture | Busy Java Developers Guide to NoSQL | Ted Neward
Architecture | Busy Java Developers Guide to NoSQL | Ted Neward
 
Pig workshop
Pig workshopPig workshop
Pig workshop
 

Mehr von 偉格 高

Mobile web application
Mobile web applicationMobile web application
Mobile web application偉格 高
 
Web Developer Tools for ICOS 2013
Web Developer Tools for ICOS 2013Web Developer Tools for ICOS 2013
Web Developer Tools for ICOS 2013偉格 高
 
Functional programming using underscorejs
Functional programming using underscorejsFunctional programming using underscorejs
Functional programming using underscorejs偉格 高
 
Module, AMD, RequireJS
Module, AMD, RequireJSModule, AMD, RequireJS
Module, AMD, RequireJS偉格 高
 
Javascript essential-pattern
Javascript essential-patternJavascript essential-pattern
Javascript essential-pattern偉格 高
 
Vim Plugin Deployment
Vim Plugin DeploymentVim Plugin Deployment
Vim Plugin Deployment偉格 高
 
WAI-ARIA is More Than Accessibility
WAI-ARIA is More Than AccessibilityWAI-ARIA is More Than Accessibility
WAI-ARIA is More Than Accessibility偉格 高
 
TOSSUG HTML5 讀書會 新標籤與表單
TOSSUG HTML5 讀書會 新標籤與表單TOSSUG HTML5 讀書會 新標籤與表單
TOSSUG HTML5 讀書會 新標籤與表單偉格 高
 
Html5 New Features
Html5 New FeaturesHtml5 New Features
Html5 New Features偉格 高
 

Mehr von 偉格 高 (13)

Web Component
Web ComponentWeb Component
Web Component
 
Mobile web application
Mobile web applicationMobile web application
Mobile web application
 
this
thisthis
this
 
Web Developer Tools for ICOS 2013
Web Developer Tools for ICOS 2013Web Developer Tools for ICOS 2013
Web Developer Tools for ICOS 2013
 
Functional programming using underscorejs
Functional programming using underscorejsFunctional programming using underscorejs
Functional programming using underscorejs
 
Module, AMD, RequireJS
Module, AMD, RequireJSModule, AMD, RequireJS
Module, AMD, RequireJS
 
Javascript essential-pattern
Javascript essential-patternJavascript essential-pattern
Javascript essential-pattern
 
Vim Plugin Deployment
Vim Plugin DeploymentVim Plugin Deployment
Vim Plugin Deployment
 
WAI-ARIA is More Than Accessibility
WAI-ARIA is More Than AccessibilityWAI-ARIA is More Than Accessibility
WAI-ARIA is More Than Accessibility
 
WAI-ARIA
WAI-ARIAWAI-ARIA
WAI-ARIA
 
TOSSUG HTML5 讀書會 新標籤與表單
TOSSUG HTML5 讀書會 新標籤與表單TOSSUG HTML5 讀書會 新標籤與表單
TOSSUG HTML5 讀書會 新標籤與表單
 
Html5 New Features
Html5 New FeaturesHtml5 New Features
Html5 New Features
 
Base2
Base2Base2
Base2
 

Kürzlich hochgeladen

activity_diagram_combine_v4_20190827.pdfactivity_diagram_combine_v4_20190827.pdf
activity_diagram_combine_v4_20190827.pdfactivity_diagram_combine_v4_20190827.pdfactivity_diagram_combine_v4_20190827.pdfactivity_diagram_combine_v4_20190827.pdf
activity_diagram_combine_v4_20190827.pdfactivity_diagram_combine_v4_20190827.pdfJamie (Taka) Wang
 
AI Fame Rush Review – Virtual Influencer Creation In Just Minutes
AI Fame Rush Review – Virtual Influencer Creation In Just MinutesAI Fame Rush Review – Virtual Influencer Creation In Just Minutes
AI Fame Rush Review – Virtual Influencer Creation In Just MinutesMd Hossain Ali
 
KubeConEU24-Monitoring Kubernetes and Cloud Spend with OpenCost
KubeConEU24-Monitoring Kubernetes and Cloud Spend with OpenCostKubeConEU24-Monitoring Kubernetes and Cloud Spend with OpenCost
KubeConEU24-Monitoring Kubernetes and Cloud Spend with OpenCostMatt Ray
 
Machine Learning Model Validation (Aijun Zhang 2024).pdf
Machine Learning Model Validation (Aijun Zhang 2024).pdfMachine Learning Model Validation (Aijun Zhang 2024).pdf
Machine Learning Model Validation (Aijun Zhang 2024).pdfAijun Zhang
 
Anypoint Code Builder , Google Pub sub connector and MuleSoft RPA
Anypoint Code Builder , Google Pub sub connector and MuleSoft RPAAnypoint Code Builder , Google Pub sub connector and MuleSoft RPA
Anypoint Code Builder , Google Pub sub connector and MuleSoft RPAshyamraj55
 
UiPath Community: AI for UiPath Automation Developers
UiPath Community: AI for UiPath Automation DevelopersUiPath Community: AI for UiPath Automation Developers
UiPath Community: AI for UiPath Automation DevelopersUiPathCommunity
 
Designing A Time bound resource download URL
Designing A Time bound resource download URLDesigning A Time bound resource download URL
Designing A Time bound resource download URLRuncy Oommen
 
UiPath Solutions Management Preview - Northern CA Chapter - March 22.pdf
UiPath Solutions Management Preview - Northern CA Chapter - March 22.pdfUiPath Solutions Management Preview - Northern CA Chapter - March 22.pdf
UiPath Solutions Management Preview - Northern CA Chapter - March 22.pdfDianaGray10
 
NIST Cybersecurity Framework (CSF) 2.0 Workshop
NIST Cybersecurity Framework (CSF) 2.0 WorkshopNIST Cybersecurity Framework (CSF) 2.0 Workshop
NIST Cybersecurity Framework (CSF) 2.0 WorkshopBachir Benyammi
 
Meet the new FSP 3000 M-Flex800™
Meet the new FSP 3000 M-Flex800™Meet the new FSP 3000 M-Flex800™
Meet the new FSP 3000 M-Flex800™Adtran
 
UiPath Studio Web workshop series - Day 7
UiPath Studio Web workshop series - Day 7UiPath Studio Web workshop series - Day 7
UiPath Studio Web workshop series - Day 7DianaGray10
 
Using IESVE for Loads, Sizing and Heat Pump Modeling to Achieve Decarbonization
Using IESVE for Loads, Sizing and Heat Pump Modeling to Achieve DecarbonizationUsing IESVE for Loads, Sizing and Heat Pump Modeling to Achieve Decarbonization
Using IESVE for Loads, Sizing and Heat Pump Modeling to Achieve DecarbonizationIES VE
 
COMPUTER 10 Lesson 8 - Building a Website
COMPUTER 10 Lesson 8 - Building a WebsiteCOMPUTER 10 Lesson 8 - Building a Website
COMPUTER 10 Lesson 8 - Building a Websitedgelyza
 
IESVE Software for Florida Code Compliance Using ASHRAE 90.1-2019
IESVE Software for Florida Code Compliance Using ASHRAE 90.1-2019IESVE Software for Florida Code Compliance Using ASHRAE 90.1-2019
IESVE Software for Florida Code Compliance Using ASHRAE 90.1-2019IES VE
 
Computer 10: Lesson 10 - Online Crimes and Hazards
Computer 10: Lesson 10 - Online Crimes and HazardsComputer 10: Lesson 10 - Online Crimes and Hazards
Computer 10: Lesson 10 - Online Crimes and HazardsSeth Reyes
 
Linked Data in Production: Moving Beyond Ontologies
Linked Data in Production: Moving Beyond OntologiesLinked Data in Production: Moving Beyond Ontologies
Linked Data in Production: Moving Beyond OntologiesDavid Newbury
 
Crea il tuo assistente AI con lo Stregatto (open source python framework)
Crea il tuo assistente AI con lo Stregatto (open source python framework)Crea il tuo assistente AI con lo Stregatto (open source python framework)
Crea il tuo assistente AI con lo Stregatto (open source python framework)Commit University
 

Kürzlich hochgeladen (20)

activity_diagram_combine_v4_20190827.pdfactivity_diagram_combine_v4_20190827.pdf
activity_diagram_combine_v4_20190827.pdfactivity_diagram_combine_v4_20190827.pdfactivity_diagram_combine_v4_20190827.pdfactivity_diagram_combine_v4_20190827.pdf
activity_diagram_combine_v4_20190827.pdfactivity_diagram_combine_v4_20190827.pdf
 
AI Fame Rush Review – Virtual Influencer Creation In Just Minutes
AI Fame Rush Review – Virtual Influencer Creation In Just MinutesAI Fame Rush Review – Virtual Influencer Creation In Just Minutes
AI Fame Rush Review – Virtual Influencer Creation In Just Minutes
 
KubeConEU24-Monitoring Kubernetes and Cloud Spend with OpenCost
KubeConEU24-Monitoring Kubernetes and Cloud Spend with OpenCostKubeConEU24-Monitoring Kubernetes and Cloud Spend with OpenCost
KubeConEU24-Monitoring Kubernetes and Cloud Spend with OpenCost
 
Machine Learning Model Validation (Aijun Zhang 2024).pdf
Machine Learning Model Validation (Aijun Zhang 2024).pdfMachine Learning Model Validation (Aijun Zhang 2024).pdf
Machine Learning Model Validation (Aijun Zhang 2024).pdf
 
Anypoint Code Builder , Google Pub sub connector and MuleSoft RPA
Anypoint Code Builder , Google Pub sub connector and MuleSoft RPAAnypoint Code Builder , Google Pub sub connector and MuleSoft RPA
Anypoint Code Builder , Google Pub sub connector and MuleSoft RPA
 
UiPath Community: AI for UiPath Automation Developers
UiPath Community: AI for UiPath Automation DevelopersUiPath Community: AI for UiPath Automation Developers
UiPath Community: AI for UiPath Automation Developers
 
Designing A Time bound resource download URL
Designing A Time bound resource download URLDesigning A Time bound resource download URL
Designing A Time bound resource download URL
 
UiPath Solutions Management Preview - Northern CA Chapter - March 22.pdf
UiPath Solutions Management Preview - Northern CA Chapter - March 22.pdfUiPath Solutions Management Preview - Northern CA Chapter - March 22.pdf
UiPath Solutions Management Preview - Northern CA Chapter - March 22.pdf
 
NIST Cybersecurity Framework (CSF) 2.0 Workshop
NIST Cybersecurity Framework (CSF) 2.0 WorkshopNIST Cybersecurity Framework (CSF) 2.0 Workshop
NIST Cybersecurity Framework (CSF) 2.0 Workshop
 
Meet the new FSP 3000 M-Flex800™
Meet the new FSP 3000 M-Flex800™Meet the new FSP 3000 M-Flex800™
Meet the new FSP 3000 M-Flex800™
 
UiPath Studio Web workshop series - Day 7
UiPath Studio Web workshop series - Day 7UiPath Studio Web workshop series - Day 7
UiPath Studio Web workshop series - Day 7
 
Using IESVE for Loads, Sizing and Heat Pump Modeling to Achieve Decarbonization
Using IESVE for Loads, Sizing and Heat Pump Modeling to Achieve DecarbonizationUsing IESVE for Loads, Sizing and Heat Pump Modeling to Achieve Decarbonization
Using IESVE for Loads, Sizing and Heat Pump Modeling to Achieve Decarbonization
 
COMPUTER 10 Lesson 8 - Building a Website
COMPUTER 10 Lesson 8 - Building a WebsiteCOMPUTER 10 Lesson 8 - Building a Website
COMPUTER 10 Lesson 8 - Building a Website
 
20230104 - machine vision
20230104 - machine vision20230104 - machine vision
20230104 - machine vision
 
IESVE Software for Florida Code Compliance Using ASHRAE 90.1-2019
IESVE Software for Florida Code Compliance Using ASHRAE 90.1-2019IESVE Software for Florida Code Compliance Using ASHRAE 90.1-2019
IESVE Software for Florida Code Compliance Using ASHRAE 90.1-2019
 
20150722 - AGV
20150722 - AGV20150722 - AGV
20150722 - AGV
 
Computer 10: Lesson 10 - Online Crimes and Hazards
Computer 10: Lesson 10 - Online Crimes and HazardsComputer 10: Lesson 10 - Online Crimes and Hazards
Computer 10: Lesson 10 - Online Crimes and Hazards
 
201610817 - edge part1
201610817 - edge part1201610817 - edge part1
201610817 - edge part1
 
Linked Data in Production: Moving Beyond Ontologies
Linked Data in Production: Moving Beyond OntologiesLinked Data in Production: Moving Beyond Ontologies
Linked Data in Production: Moving Beyond Ontologies
 
Crea il tuo assistente AI con lo Stregatto (open source python framework)
Crea il tuo assistente AI con lo Stregatto (open source python framework)Crea il tuo assistente AI con lo Stregatto (open source python framework)
Crea il tuo assistente AI con lo Stregatto (open source python framework)
 

node ffi

  • 6. How to Use libr3
  • 7. Sample 1/2 n = r3_tree_create(10);! ! int route_data = 3;! ! r3_tree_insert_routel(n, METHOD_GET, "/blog/post", ! sizeof("/blog/post") - 1, &route_data );! ! int err = r3_tree_compile(n, &errstr);
  • 8. Sample 1/2 n = r3_tree_create(10);! ! int route_data = 3;! ! r3_tree_insert_routel(n, METHOD_GET, "/blog/post", ! sizeof("/blog/post") - 1, &route_data );! ! int err = r3_tree_compile(n, &errstr); Create Tree
  • 9. Sample 1/2 n = r3_tree_create(10);! ! int route_data = 3;! ! r3_tree_insert_routel(n, METHOD_GET, "/blog/post", ! sizeof("/blog/post") - 1, &route_data );! ! int err = r3_tree_compile(n, &errstr); Insert Route
  • 10. Sample 1/2 n = r3_tree_create(10);! ! int route_data = 3;! ! r3_tree_insert_routel(n, METHOD_GET, "/blog/post", ! sizeof("/blog/post") - 1, &route_data );! ! int err = r3_tree_compile(n, &errstr); Data
  • 11. Sample 1/2 n = r3_tree_create(10);! ! int route_data = 3;! ! r3_tree_insert_routel(n, METHOD_GET, "/blog/post", ! sizeof("/blog/post") - 1, &route_data );! ! int err = r3_tree_compile(n, &errstr); Compile
  • 13. Sample 2/2 match_entry * entry = match_entry_create("/blog/post");! entry->request_method = METHOD_GET;! ! route *matched_route = r3_tree_match_route(n, entry);! matched_route->data; // The Data! ! match_entry_free(entry);! r3_tree_free(n);
  • 14. Sample 2/2 match_entry * entry = match_entry_create("/blog/post");! entry->request_method = METHOD_GET;! ! route *matched_route = r3_tree_match_route(n, entry);! matched_route->data; // The Data! ! match_entry_free(entry);! r3_tree_free(n); Create Entry
  • 15. Sample 2/2 match_entry * entry = match_entry_create("/blog/post");! entry->request_method = METHOD_GET;! ! route *matched_route = r3_tree_match_route(n, entry);! matched_route->data; // The Data! ! match_entry_free(entry);! r3_tree_free(n); Match Route
  • 16. Sample 2/2 match_entry * entry = match_entry_create("/blog/post");! entry->request_method = METHOD_GET;! ! route *matched_route = r3_tree_match_route(n, entry);! matched_route->data; // The Data! ! match_entry_free(entry);! r3_tree_free(n); Route Data
  • 20. Sample 2/2 match_entry * entry = match_entry_create(“/blog/post/1/2/3“);! entry->request_method = METHOD_GET; // Method Condition! ! route *matched_route = r3_tree_match_route(n, entry);! ! matched_route->data; // The Data! entry->vars; //Captured Vars, a string array! ! r3_tree_free(n);
  • 21. May I Use r3 in node
  • 22. Yes.
  • 23. How?
  • 24. How
  • 25. Why
  • 29. __cdecl val = sumExample(2,3) ; // push arguments to the stack, from right to left! push 3 ! push 2 ! ! ; // call the function! call _sumExample ! ! ; // cleanup the stack by adding the size of the arguments to! ; // ESP register! add esp,8 ! ! ; // copy the return value from EAX to a local variable (int c)! mov dword ptr [c],eax
  • 36. ffi Foreign Function Call ref Reference Tools ref-struct Struct Helper ref-array Array Helper
  • 37. Example var ffi = require('ffi');! ! var libm = ffi.Library('libm', {! 'ceil': [ 'double', [ 'double' ] ]! });! ! libm.ceil(1.5); // 2
  • 38. Example var ffi = require('ffi');! ! var libm = ffi.Library('libm', {! 'ceil': [ 'double', [ 'double' ] ]! });! ! libm.ceil(1.5); // 2 Library name! Use dlopen
  • 39. Example var ffi = require('ffi');! ! var libm = ffi.Library('libm', {! 'ceil': [ 'double', [ 'double' ] ]! });! ! libm.ceil(1.5); // 2 A function named ‘ceil’ return double
 Take one double parameter
  • 40. Example var ffi = require('ffi');! ! var libm = ffi.Library('libm', {! 'ceil': [ 'double', [ 'double' ] ]! });! ! libm.ceil(1.5); // 2 return type
  • 41. Example var ffi = require('ffi');! ! var libm = ffi.Library('libm', {! 'ceil': [ 'double', [ 'double' ] ]! });! ! libm.ceil(1.5); // 2 arguments type
  • 42. Types void bool byte pointer (u)short (u)int (u)int16 (u)int32 (u)int64 (u)longlong size_t float (u)char string object
  • 43. Example var ffi = require('ffi');! ! var libm = ffi.Library('libm', {! 'ceil': [ 'double', [ 'double' ] ]! });! ! libm.ceil(1.5); // 2 Call ceil
  • 45. math.h http://www.cplusplus.com/reference/cmath/ceil/ double ceil (double x); var libm = ffi.Library('libm', {! 'ceil': [ 'double', [ 'double' ] ]! });
  • 46. math.h http://www.cplusplus.com/reference/cmath/ceil/ double ceil (double x); var libm = ffi.Library('libm', {! 'ceil': [ 'double', [ 'double' ] ]! });
  • 47. math.h http://www.cplusplus.com/reference/cmath/ceil/ double ceil (double x); var libm = ffi.Library('libm', {! 'ceil': [ 'double', [ 'double' ] ]! });
  • 48. math.h http://www.cplusplus.com/reference/cmath/ceil/ double ceil (double x); var libm = ffi.Library('libm', {! 'ceil': [ 'double', [ 'double' ] ]! });
  • 49. r3.h
  • 54. struct _edge {! char * pattern; // 8 bytes! node * child; // 8 bytes! unsigned char pattern_len; // 1 byte! unsigned char opcode:4; // 4 bit! unsigned char has_slug:1; // 1 bit! }; var StructType = require('ref-struct');! ! var edge = StructType({! pattern: "string",! child: "pointer",! pattern_len: "ushort",! opcode: "uchar",! has_slug: "uchar"! });
  • 59. typedef struct {! str_array * vars;! const char * path; // current path to dispatch! int path_len; // the length of the current path! int request_method; // current request method! void * data; // route ptr! char * host; // the request host! ! ...
  • 60. typedef struct {! str_array * vars;! const char * path; // current path to dispatch! int path_len; // the length of the current path! int request_method; // current request method! void * data; // route ptr! char * host; // the request host! ! ... var ref = require('ref');! ! var str_array = StructType({ ... });! ! var match_entry = StructType({! vars: ref.refType(str_array),! path: "string",! path_len: "int",! request_method: "int",! data: "pointer",! host: "pointer",! ...
  • 69. ref.refType StructType({! var1: str_array,! var2: ref.refType(str_array),! var3: ref.refType(ref.refType(str_array)),! }); str_array var1;! str_array * var2;! str_array **var3;
  • 74. #define r3_tree_insert_path(n,p,d) r3_tree_insert_pathl_ex(n,p,s var libr3 = ffi.Library('libr3', {! "r3_tree_insert_pathl_ex": ["pointer", ["pointer", "string", " });! ! ! var r3_tree_insert_path = function (tree, path, data) {! return libr3.r3_tree_insert_pathl_ex(tree, path, path.length, };
  • 75. r3.h
  • 76. r3.h
  • 79. Now We Can Write ffi.Library Define for r3
  • 83. route * r3_tree_insert_routel(node *tree, int method,
 const char *path, int path_len, void *data);
  • 84. route * r3_tree_insert_routel(node *tree, int method,
 const char *path, int path_len, void *data);
  • 89. Example 1/2 var tree = libr3.r3_tree_create(10);! ! var data = new Buffer(data_str + 'u0000');! ! r3_tree_insert_route(tree, 'GET','/path', data);
  • 90. Example 2/2 var node = libr3.r3_tree_match_route(tree, entry);! ! var data = ref.deref(node).data; https://github.com/othree/node-r3/blob/46e29f72bbf68097ed66fd151f9ef42d5a3ede05/node-r3.js
  • 93. BUT
  • 97. Cons
  • 100. var data = new Buffer(data_str + 'u0000');
  • 101. var data = ref.readCString(ref.deref(node).data, 0);
  • 102. Cons
  • 109. data = new Buffer(data + 'u0000');! r3_tree_insert_path(this.tree, route, data); var node = r3_tree_match(this.tree, path, entry);! ! var data = ref.readCString(node.deref().data, 0);
  • 110. How to Skip Transform
  • 111. var i = this.i++;! this.data[i] = data;! ! var iref = ref.alloc('int', i);! ! libr3.r3_tree_insert_route(this.tree, method, route, iref); var node = libr3.r3_tree_match_route(this.tree, entry);! ! var index = node.deref().data.reinterpret(4).readUInt32LE(0);! ! var data = this.data[index];
  • 112. var i = this.i++;! this.data[i] = data;! ! var iref = ref.alloc('int', i);! ! libr3.r3_tree_insert_route(this.tree, method, route, iref); var node = libr3.r3_tree_match_route(this.tree, entry);! ! var index = node.deref().data.reinterpret(4).readUInt32LE(0);! ! var data = this.data[index]; Store Data
  • 114. var i = this.i++;! this.data[i] = data;! ! var iref = ref.alloc('int', i);! ! libr3.r3_tree_insert_route(this.tree, method, route, iref); var node = libr3.r3_tree_match_route(this.tree, entry);! ! var index = node.deref().data.reinterpret(4).readUInt32LE(0);! ! var data = this.data[index]; Data for r3
  • 115. var i = this.i++;! this.data[i] = data;! ! var iref = ref.alloc('int', i);! ! libr3.r3_tree_insert_route(this.tree, method, route, iref); var node = libr3.r3_tree_match_route(this.tree, entry);! ! var index = node.deref().data.reinterpret(4).readUInt32LE(0);! ! var data = this.data[index]; Resize Buffer
  • 116. var i = this.i++;! this.data[i] = data;! ! var iref = ref.alloc('int', i);! ! libr3.r3_tree_insert_route(this.tree, method, route, iref); var node = libr3.r3_tree_match_route(this.tree, entry);! ! var index = node.deref().data.reinterpret(4).readUInt32LE(0);! ! var data = this.data[index]; Read Index
  • 118. Route req/s director ~2200 node-r3 0.0.1 ~1900 node-r3 0.0.3 ~5000
  • 122. So
  • 123. Route req/s director ~2200 node-r3 0.0.1 ~1900 node-r3 0.0.3 ~5000 node-r3 0.1.0 7800~10600 Not Yet
  • 128. Hard To Find The Bug
  • 129. var Router = function (routes) {! var route, data, method, route_frag, i = 0;! this.tree = libr3.r3_tree_create(10);! this.data = [];! for (route in routes) {! this.data[i] = routes[route];! data = ref.alloc('int', i);! route = route.trim();! route_frag = route.split(' ');! if (route_frag.length > 1) {! route = route_frag[1];! method = METHODS[route_frag[0].toUpperCase()];! if (!method) { throw new Error(route_frag[0]); }! r3_tree_insert_route(this.tree, method, route, data);! } else {! r3_tree_insert_route(this.tree, 0, route, data);! }! i++;! }! libr3.r3_tree_compile(this.tree);! return this;! };
  • 130. var Router = function (routes) {! var route, data, method, route_frag, i = 0;! this.tree = libr3.r3_tree_create(10);! this.data = [];! for (route in routes) {! this.data[i] = routes[route];! data = ref.alloc('int', i);! route = route.trim();! route_frag = route.split(' ');! if (route_frag.length > 1) {! route = route_frag[1];! method = METHODS[route_frag[0].toUpperCa if (!method) { throw new Error(route_fra r3_tree_insert_route(this.tree, method, } else {! r3_tree_insert_route(this.tree, 0, route }! i++;! }! libr3.r3_tree_compile(this.tree);! return this;! };
  • 131. var Router = function (routes) {! var route, data, method, route_frag, i = 0;! this.tree = libr3.r3_tree_create(10);! this.data = [];! for (route in routes) {! this.data[i] = routes[route];! data = ref.alloc('int', i);! route = route.trim();! route_frag = route.split(' ');! if (route_frag.length > 1) {! route = route_frag[1];! method = METHODS[route_frag[0].toUpperCa if (!method) { throw new Error(route_fra r3_tree_insert_route(this.tree, method, } else {! r3_tree_insert_route(this.tree, 0, route }! i++;! }! libr3.r3_tree_compile(this.tree);! return this;! };
  • 132. var Router = function (routes) {! var route, data, method, route_frag, i = 0;! this.tree = libr3.r3_tree_create(10);! this.data = [];! for (route in routes) {! this.data[i] = routes[route];! data = ref.alloc('int', i);! route = route.trim();! route_frag = route.split(' ');! if (route_frag.length > 1) {! route = route_frag[1];! method = METHODS[route_frag[0].toUpperCa if (!method) { throw new Error(route_fra r3_tree_insert_route(this.tree, method, } else {! r3_tree_insert_route(this.tree, 0, route }! i++;! }! libr3.r3_tree_compile(this.tree);! return this;! };
  • 133. var Router = function (routes) {! var route, data, method, route_frag, i = 0;! this.tree = libr3.r3_tree_create(10);! this.data = [];! for (route in routes) {! this.data[i] = routes[route];! data = ref.alloc('int', i);! route = route.trim();! route_frag = route.split(' ');! if (route_frag.length > 1) {! route = route_frag[1];! method = METHODS[route_frag[0].toUpperCa if (!method) { throw new Error(route_fra r3_tree_insert_route(this.tree, method, } else {! r3_tree_insert_route(this.tree, 0, route }! i++;! }! libr3.r3_tree_compile(this.tree);! return this;! };
  • 134. var Router = function (routes) {! var route, data, method, route_frag, i = 0;! this.tree = libr3.r3_tree_create(10);! this.data = [];! for (route in routes) {! this.data[i] = routes[route];! data = ref.alloc('int', i);! route = route.trim();! route_frag = route.split(' ');! if (route_frag.length > 1) {! route = route_frag[1];! method = METHODS[route_frag[0].toUpperCa if (!method) { throw new Error(route_fra r3_tree_insert_route(this.tree, method, } else {! r3_tree_insert_route(this.tree, 0, route }! i++;! }! libr3.r3_tree_compile(this.tree);! return this;! };
  • 135. var Router = function (routes) {! var route, data, method, route_frag, i = 0;! this.tree = libr3.r3_tree_create(10);! this.data = [];! for (route in routes) {! this.data[i] = routes[route];! data = ref.alloc('int', i);! route = route.trim();! route_frag = route.split(' ');! if (route_frag.length > 1) {! route = route_frag[1];! method = METHODS[route_frag[0].toUpperCa if (!method) { throw new Error(route_fra r3_tree_insert_route(this.tree, method, } else {! r3_tree_insert_route(this.tree, 0, route }! i++;! }! libr3.r3_tree_compile(this.tree);! return this;! };
  • 136. var Router = function (routes) {! var route, data, method, route_frag, i = 0;! this.tree = libr3.r3_tree_create(10);! this.data = [];! for (route in routes) {! this.data[i] = routes[route];! data = ref.alloc('int', i);! route = route.trim();! route_frag = route.split(' ');! if (route_frag.length > 1) {! route = route_frag[1];! method = METHODS[route_frag[0].toUpperCa if (!method) { throw new Error(route_fra r3_tree_insert_route(this.tree, method, } else {! r3_tree_insert_route(this.tree, 0, route }! i++;! }! libr3.r3_tree_compile(this.tree);! return this;! };
  • 137. var Router = function (routes) {! var route, data, method, route_frag, i = 0;! this.tree = libr3.r3_tree_create(10);! this.data = [];! for (route in routes) {! this.data[i] = routes[route];! data = ref.alloc('int', i);! route = route.trim();! route_frag = route.split(' ');! if (route_frag.length > 1) {! route = route_frag[1];! method = METHODS[route_frag[0].toUpperCa if (!method) { throw new Error(route_fra r3_tree_insert_route(this.tree, method, } else {! r3_tree_insert_route(this.tree, 0, route }! i++;! }! libr3.r3_tree_compile(this.tree);! return this;! };
  • 138. var Router = function (routes) {! var route, data, method, route_frag, i = 0;! this.tree = libr3.r3_tree_create(10);! this.data = [];! for (route in routes) {! this.data[i] = routes[route];! data = ref.alloc('int', i);! route = route.trim();! route_frag = route.split(' ');! if (route_frag.length > 1) {! route = route_frag[1];! method = METHODS[route_frag[0].toUpperCa if (!method) { throw new Error(route_fra r3_tree_insert_route(this.tree, method, } else {! r3_tree_insert_route(this.tree, 0, route }! i++;! }! libr3.r3_tree_compile(this.tree);! return this;! };
  • 140. var Router = function (routes) {! var route, data, method, route_frag, i = 0;! this.tree = libr3.r3_tree_create(10);! this.data = [];! for (route in routes) {! this.data[i] = routes[route];! data = ref.alloc('int', i);! route = route.trim();! route_frag = route.split(' ');! if (route_frag.length > 1) {! route = route_frag[1];! method = METHODS[route_frag[0].toUpperCase()];! if (!method) { throw new Error(route_frag[0]); }! r3_tree_insert_route(this.tree, method, route, data);! } else {! r3_tree_insert_route(this.tree, 0, route, data);! }! i++;! }! libr3.r3_tree_compile(this.tree);! return this;! };
  • 142. var Router = function (routes) {! var route, data, method, route_frag, i = 0;! this.tree = libr3.r3_tree_create(10);! this.data = [];! this.index = [];! for (route in routes) {! this.data[i] = routes[route];! data = ref.alloc('int', i);! this.index[i] = data; // prevent GC! route = route.trim();! route_frag = route.split(' ');! if (route_frag.length > 1) {! route = route_frag[1];! method = METHODS[route_frag[0].toUpperCase()];! if (!method) { throw new Error(route_frag[0]); }! r3_tree_insert_route(this.tree, method, route, data);! } else {! r3_tree_insert_route(this.tree, 0, route, data);! }! i++;! }! libr3.r3_tree_compile(this.tree);! return this;! };
  • 146. var Router = require('node-r3').Router;! ! var router = new Router({! "/foo": "data string",! "/foo/bar": function () {},! "/foo/bar/qoo": {obj: 1},! });! ! var dispatched = router.match("/foo");! ! router.free();
  • 147. var router = new Router({! "/": handler,! "/foo": fooHandler,! "/foo/{id}": fooHandler,! "POST /me": postMeHandler,! "GET /me": getMeHandler,! "POST|GET /post": postHandler,! });! ! var server = http.createServer(! router.httpHandler(notfound)! );
  • 148. Handler Function function (req, res, captures) array