Last active
March 30, 2017 14:53
-
-
Save wshager/edf7bb5d58d4873fea88 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"use strict"; | |
var ffi = require('ffi'); | |
var ref = require('ref'); | |
var Struct = require('ref-struct'); | |
var util = require("util"); | |
var ups_status_t = ref.types.int; | |
var ups_env_t = Struct(); | |
var ups_db_t = Struct(); | |
var ups_cursor_t = Struct(); | |
var ups_txn_t = Struct(); | |
var void_ptr = ref.refType(ref.types.void); | |
var ups_parameter_t = Struct({ | |
'name':'int', | |
'value':'long' | |
}); | |
var ups_key_t = Struct({ | |
'size':'uint16', | |
'data': ref.types.CString, | |
'flags':'uint32', | |
'_flags':'uint32' | |
}); | |
var ups_record_t = Struct({ | |
'size':'uint32', | |
'data': ref.types.CString, | |
'flags':'uint32' | |
}); | |
var ups_status_t_ptr = ref.refType(ups_status_t); | |
var ups_env_t_ptr = ref.refType(ups_env_t); | |
var ups_env_t_ptr_ptr = ref.refType(ups_env_t_ptr); | |
var ups_db_t_ptr = ref.refType(ups_db_t); | |
var ups_db_t_ptr_ptr = ref.refType(ups_db_t_ptr); | |
var ups_cursor_t_ptr = ref.refType(ups_cursor_t); | |
var ups_cursor_t_ptr_ptr = ref.refType(ups_cursor_t_ptr); | |
var ups_txn_t_ptr = ref.refType(ups_txn_t); | |
var ups_txn_t_ptr_ptr = ref.refType(ups_txn_t_ptr); | |
var ups_parameter_t_ptr = ref.refType(ups_parameter_t); | |
var ups_key_t_ptr = ref.refType(ups_key_t); | |
var ups_record_t_ptr = ref.refType(ups_record_t); | |
var ups = ffi.Library('upscaledb', { | |
'ups_env_create': [ ups_status_t, [ups_env_t_ptr_ptr, 'string', 'int', 'int', ups_parameter_t_ptr]], | |
'ups_env_open': [ ups_status_t, [ups_env_t_ptr_ptr, 'string', 'int', ups_parameter_t_ptr]], | |
'ups_env_close': [ ups_status_t, [ups_env_t_ptr, 'int']], | |
'ups_env_create_db': [ ups_status_t, [ups_env_t_ptr, ups_db_t_ptr_ptr, 'int', 'int', ups_parameter_t_ptr]], | |
'ups_env_open_db': [ups_status_t, [ups_env_t_ptr, ups_db_t_ptr_ptr, 'int', 'int', ups_parameter_t_ptr]], | |
'ups_db_close': [ups_status_t, [ups_db_t_ptr, 'int']], | |
'ups_cursor_create': [ups_status_t, [ups_cursor_t_ptr_ptr,ups_db_t_ptr,'pointer','int']], | |
'ups_cursor_move': [ups_status_t, [ups_cursor_t_ptr,ups_key_t_ptr,ups_record_t_ptr,'uint32']], | |
'ups_cursor_close': [ups_status_t, [ups_cursor_t_ptr]], | |
'ups_txn_begin': [ups_status_t, [ups_txn_t_ptr_ptr, ups_env_t_ptr, 'string', 'pointer', 'int']], | |
'ups_db_insert': [ups_status_t, [ups_db_t_ptr, ups_txn_t_ptr, ups_key_t_ptr, ups_record_t_ptr, 'uint32']], | |
'ups_cursor_erase': [ups_status_t, [ups_cursor_t_ptr, 'uint32']], | |
'ups_strerror': ['string', [ups_status_t]] | |
}); | |
var env = create_env(__dirname + "\\test.db"); | |
var db = create_db(env,1); | |
//var env = open_env(__dirname + "\\test.db"); | |
//var db = open_db(env,1); | |
function makeGarbage(l){ | |
var str = "" | |
for(var i = 0; i<l; i++){ | |
var cp = 65 + Math.floor(Math.random() * 57); | |
if(cp > 90 && cp < 97) { | |
if(l>100) str += " "; | |
continue; | |
} | |
str += String.fromCodePoint(cp); | |
} | |
return str; | |
} | |
for(var i=0;i<10;i++){ | |
var k = makeGarbage(50); | |
var v = makeGarbage(150); | |
insert(db,k,v); | |
} | |
var cursor = create_cursor(db,null); | |
walk(cursor); | |
close_cursor(cursor); | |
close_db(db); | |
close_env(env); | |
function check_error(st, description) { | |
var buf = ups.ups_strerror(st); | |
console.log(st, buf.toString(),description); | |
} | |
function insert(db, key, value) { | |
//var txn = begin_txn(env); | |
var key2 = ref.allocCString(key); | |
var value2 = ref.allocCString(value); | |
var k = new ups_key_t({size:key2.byteLength, data:key2, flags:0}); | |
var r = new ups_record_t({size:value2.byteLength, data:value2, flags:0}); | |
var st = ups.ups_db_insert(db.deref(), null, k.ref(), r.ref(), 0); | |
check_error(st, "ups_db_insert"); | |
} | |
function create_env(name){ | |
var env = ref.alloc(ups_env_t_ptr_ptr); | |
var st = ups.ups_env_create(env, name, null, null, null); | |
check_error(st, "ups_env_create"); | |
return env; | |
} | |
function open_env(name) { | |
var env = ref.alloc(ups_env_t_ptr_ptr); | |
var st = ups.ups_env_open(env, name, 131072, null); | |
check_error(st, "ups_env_open"); | |
return env; | |
} | |
function open_db(env, nr){ | |
var db = ref.alloc(ups_db_t_ptr_ptr); | |
var st = ups.ups_env_open_db(env.deref(), db, nr, null, null); | |
check_error(st, "ups_env_open_db"); | |
return db; | |
} | |
function create_db(env, nr){ | |
var db = ref.alloc(ups_db_t_ptr_ptr); | |
var st = ups.ups_env_create_db(env.deref(), db, nr, null, null); | |
check_error(st, "ups_env_create_db"); | |
return db; | |
} | |
function close_db(db) { | |
var st = ups.ups_db_close(db, 1); | |
check_error(st, "ups_db_close"); | |
} | |
function close_env(env) { | |
var st = ups.ups_env_close(env.deref(), 1); | |
check_error(st, "ups_env_close"); | |
} | |
function begin_txn(env) { | |
var txn = ref.alloc(ups_txn_t_ptr_ptr); | |
var st = ups.ups_txn_begin(txn,env.deref(),new Buffer(''), ref.alloc(ref.types.void).ref(), null); | |
check_error(st, "ups_txn_begin"); | |
return txn; | |
} | |
function create_cursor(db,txn){ | |
var cursor = ref.alloc(ups_cursor_t_ptr_ptr); | |
var st = ups.ups_cursor_create(cursor, db.deref(), txn ? txn.deref() : null, 0); | |
check_error(st, "ups_cursor_create"); | |
return cursor; | |
} | |
function close_cursor(cursor) { | |
var st = ups.ups_cursor_close(cursor.deref()); | |
check_error(st, "ups_cursor_close"); | |
} | |
// TODO more of this | |
const UPS_CURSOR_FIRST = 1; | |
const UPS_CURSOR_LAST = 2; | |
const UPS_CURSOR_NEXT = 4; | |
const UPS_CURSOR_PREVIOUS = 8; | |
function move_cursor(cursor,key, record,flags){ | |
// TODO here the javascript-like return logic fails... | |
var st = ups.ups_cursor_move(cursor.deref(), key.ref(), record.ref(), flags);//1 | |
check_error(st, "ups_cursor_move first"); | |
if(!st && cb) cb(key.deref().data,record.deref().data); | |
return cursor; | |
}; | |
function walk(cursor) { | |
var key = (new ups_key_t({size:0,data:ref.alloc(ref.types.CString),flags:0})).ref(); | |
var record = (new ups_record_t({size:0,data:ref.alloc(ref.types.CString),flags:0})).ref(); | |
var st = ups.ups_cursor_move(cursor.deref(), key, record, 1);//1 | |
check_error(st, "ups_cursor_move first"); | |
if(!!st) return; | |
// print key+record, erase, then move to the next and repeat | |
do { | |
if(st === 0) { | |
console.log("key",key.deref().data.toString()); | |
console.log("record",record.deref().data.toString()); | |
// clean up | |
check_error(ups.ups_cursor_erase(cursor.deref(),0), "ups_cursor_erase"); | |
} | |
st = ups.ups_cursor_move(cursor.deref(), key, record, 4);//4 | |
check_error(st, "ups_cursor_move next"); | |
} while(!st); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment