Skip to content

Instantly share code, notes, and snippets.

@wshager
Last active March 30, 2017 14:53
Show Gist options
  • Save wshager/edf7bb5d58d4873fea88 to your computer and use it in GitHub Desktop.
Save wshager/edf7bb5d58d4873fea88 to your computer and use it in GitHub Desktop.
"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