├── pull.git ├── clone.git ├── setargv.obj ├── win_flex.exe ├── win_bison.exe ├── data for flex-bison.zip ├── jsscripts ├── test_int.js ├── test_tern.js ├── test_sort.js ├── test_semi.js ├── test_ftw.js ├── test_toks.js ├── test_ifthenelse.js ├── test_concat.js ├── test_conv.js ├── test_args.js ├── test_parse.js ├── test_for.js ├── test_name.js ├── test_math.js ├── test_rel.js ├── test_str1.js ├── test_comment.js ├── test_assign.js ├── test_date.js ├── test_comp.js ├── test_var.js ├── test_fcn.js ├── test_proto.js ├── test_obj.js ├── test_this.js ├── test_num.js ├── test_dbdocs.js ├── test_fcn2.js ├── test_es6scope.js ├── test_array.js ├── test_enum.js ├── test_num64.js ├── test_num32.js ├── test_db.js ├── test_xtn.js ├── test_bin.js ├── test_props.js ├── test_json.js ├── test_dbartree.js ├── test_dbbtree.js ├── test_dbidx.js ├── test_dbupdate.js └── test_str.js ├── js_malloc.h ├── .gitmodules ├── oldjsdb ├── jsdb_dbupdate.c ├── jsdb_dbcolindex.c ├── jsdb_dbart.c ├── jsdb_rwlock.h ├── jsdb_dbpq.h ├── jsdb_rwlock2.h ├── jsdb_dbbtreeindex.c ├── jsdb_util.h ├── jsdb_dbdocs.h ├── jsdb_dbbtree.c ├── jsdb_dbartindex.c ├── jsdb_dbtxn.c ├── jsdb_rwlock.c ├── jsdb_dbbtreecursor.c ├── jsdb_dbpq.c ├── jsdb_dbbtreeinsert.c ├── jsdb_dbarena.h ├── jsdb_dbbtreelatch.c ├── jsdb_dbcol.h ├── jsdb_dbcursor.c ├── jsdb_dbartdelete.c └── jsdb_rwlock2.c ├── mongo ├── test_timing1.js ├── test_timing0.js ├── jsDbBase.js ├── mongod.js ├── test_mongo.js ├── jsDbColl.js ├── jsDbFind.js └── js_dbinsert.c ├── js_props.h ├── js_string.h ├── js_math.h ├── sunspider ├── bitops-bits-in-byte.js ├── controlflow-recursive.js ├── bitops-nsieve-bits.js ├── bitops-nsieve-bits64.js ├── access-nsieve.js ├── bitops-3bit-bits-in-byte.js ├── math-spectral-norm.js ├── access-binary-trees.js ├── math-partial-sums.js ├── access-fannkuch.js ├── string-fasta.js ├── string-validate-input.js ├── 3d-morph.js └── math-cordic.js ├── js_error.h ├── makefile ├── js_vector.h ├── data ├── c-skel.m4 ├── c++-skel.m4 ├── java-skel.m4 ├── local.mk ├── README ├── c-like.m4 ├── stack.hh └── xslt │ └── bison.xsl ├── js_db.h ├── javascript-database.sln ├── systemBase.js ├── js_error.c ├── js_dbindex.h ├── js_eval.h ├── tests.bash ├── js_malloc.c ├── speed1.js ├── apache └── mod_jsdb.c ├── js_parse.c ├── js_vector.c ├── speed2.js ├── .gitattributes ├── speed5.js ├── tests.bat ├── speed3.js ├── speed4.js ├── readme.md ├── js_dbver.c ├── js_dbiterator.c ├── systemObj.js ├── systemMath.js └── js_dbcursor.c /pull.git: -------------------------------------------------------------------------------- 1 | git pull --recurse-submodules 2 | git submodule update --remote 3 | -------------------------------------------------------------------------------- /clone.git: -------------------------------------------------------------------------------- 1 | git clone --recursive git://github.com/malbrain/javascript-database 2 | -------------------------------------------------------------------------------- /setargv.obj: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/malbrain/javascript-database/HEAD/setargv.obj -------------------------------------------------------------------------------- /win_flex.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/malbrain/javascript-database/HEAD/win_flex.exe -------------------------------------------------------------------------------- /win_bison.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/malbrain/javascript-database/HEAD/win_bison.exe -------------------------------------------------------------------------------- /data for flex-bison.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/malbrain/javascript-database/HEAD/data for flex-bison.zip -------------------------------------------------------------------------------- /jsscripts/test_int.js: -------------------------------------------------------------------------------- 1 | print("\n\nbegin test_int.js"); 2 | print("------------------"); 3 | var i = 2.0; 4 | print("Expecting 2.0: ", i); 5 | -------------------------------------------------------------------------------- /jsscripts/test_tern.js: -------------------------------------------------------------------------------- 1 | print("\n\nbegin test_tern.js"); 2 | print("------------------"); 3 | var x = 1>2 ? "good" : 1<2 ? "good2" : "bad"; 4 | print("expecting good2: ", x); 5 | -------------------------------------------------------------------------------- /jsscripts/test_sort.js: -------------------------------------------------------------------------------- 1 | print("\n\nbegin test_sort.js"); 2 | print("------------------"); 3 | var source = [9,3,8,1]; 4 | print("Sorting: ", source, " result: ", source.sort()); 5 | -------------------------------------------------------------------------------- /jsscripts/test_semi.js: -------------------------------------------------------------------------------- 1 | print("\n\nbegin test_semi.js"); 2 | print("------------------"); 3 | var x = 2 * 3.0; 4 | print("Expecting: 6.0: ", x);; 5 | print("Empty Statement Ignored"); 6 | -------------------------------------------------------------------------------- /jsscripts/test_ftw.js: -------------------------------------------------------------------------------- 1 | print("\n\nbegin test_ftw.js"); 2 | print("------------------"); 3 | 4 | var list = jsdb_listFiles("."); 5 | print("Expecting sorted current directory: ", list.sort()); 6 | -------------------------------------------------------------------------------- /js_malloc.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "database/db.h" 4 | 5 | // 6 | // Reference Counting 7 | // 8 | 9 | typedef struct RawObj { 10 | uint32_t weakCnt[1]; 11 | uint32_t refCnt[1]; 12 | } rawobj_t; 13 | 14 | -------------------------------------------------------------------------------- /jsscripts/test_toks.js: -------------------------------------------------------------------------------- 1 | print("\n\nbegin test_toks.js"); 2 | print("------------------"); 3 | var str = "db.collection.test"; 4 | print("string = '", str, "'"); 5 | var toks = str.split("."); 6 | 7 | print("split: ", toks); 8 | -------------------------------------------------------------------------------- /jsscripts/test_ifthenelse.js: -------------------------------------------------------------------------------- 1 | print("\n\nbegin test_ifthenelse.js"); 2 | print("------------------"); 3 | var a = 1, b = 2; 4 | 5 | print("expecting 2:"); 6 | 7 | if (a) { 8 | if (b) print(b); 9 | } else 10 | print (a); 11 | -------------------------------------------------------------------------------- /jsscripts/test_concat.js: -------------------------------------------------------------------------------- 1 | print("\n\nbegin test_concat.js"); 2 | print("------------------"); 3 | var obj = { name:"abcd", val:3 }; 4 | var obj2 = { name:"123", val:4 }; 5 | 6 | var tst = obj.name + obj2.name; 7 | print("expect abcd123: ", tst); 8 | -------------------------------------------------------------------------------- /jsscripts/test_conv.js: -------------------------------------------------------------------------------- 1 | print("\n\nbegin test_conv.js"); 2 | print("------------------"); 3 | print("expect false: ", "abc" == 3); 4 | print("expect true : ", "003" == 3); 5 | print("expect true : ", "3.0" == 3); 6 | print("expect true : ", "3.5" == 3.5); 7 | -------------------------------------------------------------------------------- /jsscripts/test_args.js: -------------------------------------------------------------------------------- 1 | print("\n\nbegin test_args.js"); 2 | print("------------------"); 3 | 4 | function Test() { 5 | print(arguments); 6 | print(arguments[0]); 7 | } 8 | 9 | print("Test arguments & arguments[0] for Test(1,2,3)"); 10 | Test(1,2,3); 11 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "database"] 2 | path = database 3 | url = ../database 4 | [submodule "rwlock"] 5 | path = rwlock 6 | url = https://github.com/malbrain/rwlock 7 | [submodule "mutex"] 8 | path = mutex 9 | url = https://github.com/malbrain/mutex 10 | -------------------------------------------------------------------------------- /jsscripts/test_parse.js: -------------------------------------------------------------------------------- 1 | print("\n\nbegin test_parse.js"); 2 | print("------------------"); 3 | print('parseInt("1") = ', parseInt("1")); 4 | print('parseFloat("1.2") = ', parseFloat("1.2")); 5 | 6 | print('parseInt("a") = ', parseInt("a")); 7 | print('parseFloat("a") = ', parseFloat("a")); 8 | -------------------------------------------------------------------------------- /oldjsdb/jsdb_dbupdate.c: -------------------------------------------------------------------------------- 1 | #include "jsdb.h" 2 | #include "jsdb_db.h" 3 | 4 | // updateDoc (docStore, docArray, &docIdArray, &docCount) 5 | 6 | value_t jsdb_updateDoc(uint32_t args, environment_t *env) { 7 | value_t s; 8 | 9 | s.bits = vt_status; 10 | return s.status = OK, s; 11 | } 12 | 13 | -------------------------------------------------------------------------------- /jsscripts/test_for.js: -------------------------------------------------------------------------------- 1 | print("\n\nbegin test_for.js"); 2 | print("------------------"); 3 | var array = [3,2,1]; 4 | 5 | print("array: ", array); 6 | 7 | for( var idx in array) 8 | print("idx values in array: ", idx); 9 | 10 | for( var val of array) 11 | print("val values of array: ", val); 12 | -------------------------------------------------------------------------------- /jsscripts/test_name.js: -------------------------------------------------------------------------------- 1 | print("\n\nbegin test_name.js"); 2 | print("------------------"); 3 | 4 | function Test (a,b,c) { 5 | return { test : a, test2:b, test3:c, name : Test.displayName }; 6 | } 7 | 8 | print("Call Test(1,2,3), expecting { test : 1, test2:2, test3:3, name : Test.displayName }: ", Test(1,2,3)); 9 | -------------------------------------------------------------------------------- /oldjsdb/jsdb_dbcolindex.c: -------------------------------------------------------------------------------- 1 | #include "jsdb.h" 2 | #include "jsdb_db.h" 3 | 4 | bool colindex_hasdup (DbMap *index, DbAddr *base, uint8_t *suffix) { 5 | 6 | return false; 7 | } 8 | 9 | bool colindexKey (DbMap *index, uint8_t *keyBuff, uint32_t keyLen, uint8_t *suffix, uint32_t set) { 10 | return false; 11 | } 12 | -------------------------------------------------------------------------------- /jsscripts/test_math.js: -------------------------------------------------------------------------------- 1 | print("\n\nbegin test_math.js"); 2 | print("------------------"); 3 | var v = [1.2,2.2,3.2]; 4 | print("Vector :", v); 5 | 6 | print("Multiplied: ", v[0] * v[1] * v[2]); 7 | 8 | var a = 1; 9 | 10 | for(var i = 0; i < v.length; i++) 11 | a /= v[i]; 12 | 13 | print("1/", v[0] * v[1] * v[2], " = ", a); 14 | -------------------------------------------------------------------------------- /jsscripts/test_rel.js: -------------------------------------------------------------------------------- 1 | print("\n\nbegin test_rel.js"); 2 | print("------------------"); 3 | print('"a" > "b" = ', "a" > "b"); 4 | print('"a" < "b" = ', "a" < "b"); 5 | print('"aa" < "aa" = ', "aa" < "aa"); 6 | print('"aa" <= "aa" = ', "aa" <= "aa"); 7 | print('"aa" <= "aab" = ', "aa" <= "aab"); 8 | print('"aa" > "aab" = ', "aa" > "aab"); 9 | -------------------------------------------------------------------------------- /jsscripts/test_str1.js: -------------------------------------------------------------------------------- 1 | print("\n\nbegin test_str1.js"); 2 | print("------------------"); 3 | var array = ["a", 2, 3, "d"]; 4 | 5 | print('Expecting ["a", 2, 3, "d"] : ', array); 6 | 7 | var str = " "; 8 | 9 | for(var i = 0; i < 1024 * 1024; i++) 10 | str += " "; 11 | 12 | print("Expecting 1048577: ", str.length); 13 | 14 | -------------------------------------------------------------------------------- /jsscripts/test_comment.js: -------------------------------------------------------------------------------- 1 | print("\n\nbegin test_comment.js"); 2 | print("------------------"); 3 | print(1); 4 | 5 | /* 6 | * this is a long comment 7 | */ 8 | 9 | print("begin: ", 'multi-line string value\ 10 | that continues on two lines', ":end"); 11 | 12 | print("\"", 'multi-line string value\ 13 | that continues on two lines', "\""); 14 | -------------------------------------------------------------------------------- /jsscripts/test_assign.js: -------------------------------------------------------------------------------- 1 | print("\n\nbegin test_assign.js"); 2 | print("------------------"); 3 | 4 | var a = 1, b = 2, c, d = 4; 5 | 6 | print("Expecting 3: ", c = d = a + b); 7 | print("Expecting 1:2:3:3: ", a,":",b,":",c,":",d); 8 | 9 | a += 2.5; 10 | print("Expecting 3.5: ", a); 11 | 12 | var f = 5.5; 13 | f += 3; 14 | 15 | print("Expecting 8.5: ", f); 16 | -------------------------------------------------------------------------------- /jsscripts/test_date.js: -------------------------------------------------------------------------------- 1 | print("\n\nbegin test_date.js"); 2 | print("------------------"); 3 | print("expect date value : ", Date()); 4 | 5 | var now = Date(); 6 | now += 2000; 7 | print("expect date value + 2 seconds : ", now); 8 | 9 | var date = new Date(); 10 | date.setTime(1000); 11 | print("expect setTime 1/1/1970 - tz + 1sec: ", date); 12 | -------------------------------------------------------------------------------- /jsscripts/test_comp.js: -------------------------------------------------------------------------------- 1 | print("\n\nbegin test_comp.js"); 2 | print("------------------"); 3 | print("expect true : ", "a" < "b"); 4 | print("expect true : ", "a" < "ab"); 5 | print("expect false: ", "ab" < "a"); 6 | print("expect false: ", "ab" == "a"); 7 | print("expect true : ", "ab" != "a"); 8 | print("expect false: ", "ab" <= "a"); 9 | print("expect true : ", "ab" >= "a"); 10 | -------------------------------------------------------------------------------- /jsscripts/test_var.js: -------------------------------------------------------------------------------- 1 | print("\n\nbegin test_var.js"); 2 | print("------------------"); 3 | var a,b,c,d,e,f,g,h,i,j; 4 | 5 | var array = []; 6 | 7 | for(var i = 0; i < 10; i++) 8 | array[i] = i; 9 | 10 | print ("array w/10 consecutive elements: ", array); 11 | 12 | var validation = []; 13 | 14 | validation[20] = 2889.0000000000045; 15 | 16 | print("expecting 2889.0000000000045: ", validation[20]); 17 | 18 | -------------------------------------------------------------------------------- /mongo/test_timing1.js: -------------------------------------------------------------------------------- 1 | var store, txn, db, new; 2 | initDatabase(&db, "test", 0, true); 3 | openDocStore(&store, db, "basic1", 1024 * 1024, true, &new); 4 | if(new) print("created new DocStore"); 5 | 6 | 7 | openIndex(store, &index, "_id_"); 8 | createCursor(store, snap, &iterator); 9 | 10 | while (nextRec(iterator, &id, &record)) { 11 | if (record.a == 500000) 12 | print(id, record); 13 | } 14 | 15 | closeIterator(iterator); 16 | 17 | -------------------------------------------------------------------------------- /jsscripts/test_fcn.js: -------------------------------------------------------------------------------- 1 | print("\n\nbegin test_fcn.js"); 2 | print("------------------"); 3 | 4 | function x(y,z){ 5 | if(z){ 6 | return 1; 7 | }else{ 8 | return 2; 9 | } 10 | } 11 | 12 | print("expecting 1: ", x("yes1", true)); 13 | 14 | function a(y,z){ 15 | if(z){ 16 | return [y,z]; 17 | }else{ 18 | return ["no z"]; 19 | } 20 | } 21 | 22 | print("Expecting 1:", x("yes1", true)); 23 | print('Expecting ["yes2", true] :', a("yes2", true)); 24 | 25 | -------------------------------------------------------------------------------- /mongo/test_timing0.js: -------------------------------------------------------------------------------- 1 | var store, txn; 2 | initEngine(); 3 | 4 | createRecStore(1024 * 1024, &store); 5 | createTxn(&txn); 6 | 7 | var count = 1; 8 | 9 | while ( count ) { 10 | var record = { 11 | a : count, 12 | b : "a string body" 13 | }; 14 | var id, cnt; 15 | var array = [ record, record ]; 16 | insertRec(store, txn, array, &id, &cnt); 17 | print(id); 18 | count -= 1; 19 | } 20 | 21 | commitTxn(txn); 22 | 23 | -------------------------------------------------------------------------------- /jsscripts/test_proto.js: -------------------------------------------------------------------------------- 1 | print("\n\nbegin test_proto.js"); 2 | print("------------------"); 3 | 4 | var o = { 5 | prop: 37, 6 | f: function() { 7 | return this.prop; 8 | } 9 | }; 10 | 11 | print("Array prototype: ", Array.prototype); 12 | print("Object prototype: ", Object.prototype); 13 | print("Function prototype: ", Function.prototype); 14 | 15 | print("Expecting 37: ", o.f()); 16 | 17 | function dbl(a) { return a + a;} 18 | 19 | print("Fcn dbl: ", dbl); 20 | -------------------------------------------------------------------------------- /oldjsdb/jsdb_dbart.c: -------------------------------------------------------------------------------- 1 | #include "jsdb.h" 2 | #include "jsdb_db.h" 3 | 4 | bool addSlotToWaitList(DbMap *index, uint32_t set, DbAddr slot) { 5 | DbAddr *head = artIndexAddr(index)->freeLists[set][slot.type].head; 6 | DbAddr *tail = artIndexAddr(index)->freeLists[set][slot.type].tail; 7 | 8 | if (addSlotToFrame(index, head, slot.bits)) { 9 | if (head->addr && !tail->addr) 10 | tail->addr = head->addr; 11 | } else 12 | return false; 13 | 14 | return true; 15 | } 16 | 17 | -------------------------------------------------------------------------------- /js_props.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // built-in property functions 4 | 5 | typedef value_t (*propFcn)(value_t *args, value_t thisVal, environment_t *env); 6 | typedef value_t (*propVal)(value_t val, bool lval); 7 | 8 | typedef struct { 9 | propVal fcn; 10 | char *name; 11 | bool isBase; // property in base, not in protoObj 12 | value_t str; 13 | } PropVal; 14 | 15 | typedef struct { 16 | propFcn fcn; 17 | char *name; 18 | bool isBase; // function in base, not in protoObj 19 | value_t str; 20 | } PropFcn; 21 | 22 | void processOptions(Params *params, value_t options); 23 | -------------------------------------------------------------------------------- /js_string.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | extern string_t UndefinedStr; 4 | extern string_t EmptyStr; 5 | extern string_t QuoteStr; 6 | extern string_t ColonStr; 7 | extern string_t CommaStr; 8 | extern string_t LeftBraceStr; 9 | extern string_t RightBraceStr; 10 | extern string_t LeftBrackStr; 11 | extern string_t RightBrackStr; 12 | extern string_t TrueStr; 13 | extern string_t FalseStr; 14 | extern string_t InfinityStr; 15 | extern string_t MInfinityStr; 16 | extern string_t NullStr; 17 | extern string_t NaNStr; 18 | extern string_t ToStringStr; 19 | extern string_t ValueOfStr; 20 | 21 | -------------------------------------------------------------------------------- /js_math.h: -------------------------------------------------------------------------------- 1 | // built-in math functions 2 | 3 | enum MathEnum { 4 | math_acos, 5 | math_acosh, 6 | math_asin, 7 | math_asinh, 8 | math_atan, 9 | math_atanh, 10 | math_atan2, 11 | math_cbrt, 12 | math_ceil, 13 | math_clz32, 14 | math_cos, 15 | math_cosh, 16 | math_exp, 17 | math_expm1, 18 | math_floor, 19 | math_fround, 20 | math_imul, 21 | math_log, 22 | math_log1p, 23 | math_log10, 24 | math_log2, 25 | math_pow, 26 | math_random, 27 | math_round, 28 | math_sign, 29 | math_sin, 30 | math_sinh, 31 | math_sqrt, 32 | math_tan, 33 | math_tanh, 34 | math_trunc 35 | }; 36 | -------------------------------------------------------------------------------- /jsscripts/test_obj.js: -------------------------------------------------------------------------------- 1 | print("\n\nbegin test_obj.js"); 2 | print("------------------"); 3 | 4 | var doc = { field: 1,}; 5 | print("Expecting { field: 1,} : ", doc); 6 | 7 | doc = [1,2]; 8 | print("Expecting [1,2] : ", doc); 9 | 10 | function NewObj (a,b,c) { 11 | this.sum = a+b+c; 12 | } 13 | 14 | NewObj.prototype.type = "NewObj"; 15 | 16 | var test = new NewObj(1,2,3); 17 | 18 | print("Expecting NewObj: ", test.type); 19 | 20 | var nested = {field: 1, sub: {a:1, b:2}}; 21 | nested.sub.a = "changed"; 22 | 23 | print("Expecting {\"field\": 1, \"sub\": {\"a\":\"changed\", \"b\":2}}: ", nested); 24 | 25 | -------------------------------------------------------------------------------- /mongo/jsDbBase.js: -------------------------------------------------------------------------------- 1 | var debug = true; 2 | 3 | var Db = function(dbname) { 4 | this._dbname = dbname; 5 | this._db = jsdb_openDatabase(dbname, Db._onDisk); 6 | }; 7 | 8 | Db.prototype.beginTxn = function() { 9 | this._dbtxn = jsdb_beginTxn(this._handle); 10 | }; 11 | 12 | Db.prototype.commitTxn = function() { 13 | jsdb_commitTxn(this._handle, this._dbtxn); 14 | this._dbtxn = null; 15 | }; 16 | 17 | Db.prototype.rollbackTxn = function() { 18 | jsdb_rollbackTxn(this._handle, this._dbtxn); 19 | this._dbtxn = null; 20 | }; 21 | 22 | Db.catalog = {}; 23 | Db.inMem = []; 24 | 25 | Db._defaultSize = 1024 * 1024; 26 | Db._autoIndexId = true; 27 | Db._onDisk = true; 28 | -------------------------------------------------------------------------------- /jsscripts/test_this.js: -------------------------------------------------------------------------------- 1 | print("\n\nbegin test_this.js"); 2 | print("------------------"); 3 | 4 | var list = jsdb_listFiles("dbdata"); 5 | 6 | for (var file of list) 7 | if (file.startsWith("testing")) 8 | jsdb_deleteFile("dbdata/" + file); 9 | 10 | jsdb_deleteFile("dbdata/Txns"); 11 | 12 | 13 | function Db(dbname, options) { 14 | if (!this) 15 | return new Db(dbname, options); 16 | 17 | var opt = DbOptParse(Db, options); 18 | var handle = jsdb_openDatabase(dbname, opt); 19 | 20 | this.name = dbname; 21 | this.options = options; 22 | this.setValue(handle); 23 | } 24 | 25 | print("start"); 26 | var db = new Db("testing", {onDisk:false}); 27 | print("db = ", db); 28 | -------------------------------------------------------------------------------- /oldjsdb/jsdb_rwlock.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "jsdb_util.h" 4 | 5 | typedef union { 6 | struct { 7 | volatile short xcl[1]; 8 | volatile short waiters[1]; 9 | } bits[1]; 10 | #ifdef _WIN32 11 | volatile long value[1]; 12 | #else 13 | volatile uint32_t value[1]; 14 | #endif 15 | } Mutex; 16 | 17 | // definition for reader/writer lock implementation 18 | 19 | typedef struct { 20 | volatile short readers; 21 | uint8_t type; 22 | Mutex xcl[1]; 23 | Mutex wrt[1]; 24 | } RWLock; 25 | 26 | 27 | void bt_mutexlock(Mutex *latch); 28 | int bt_mutextry(Mutex *latch); 29 | void bt_releasemutex(Mutex *latch); 30 | 31 | void writeLock (RWLock *lock); 32 | void readLock (RWLock *lock); 33 | void rwUnlock (RWLock *lock); 34 | -------------------------------------------------------------------------------- /jsscripts/test_num.js: -------------------------------------------------------------------------------- 1 | print("\n\nbegin test_num.js"); 2 | print("------------------"); 3 | print("(10240<<4) + 31 >> 5: ", (10240<<4) + 31 >> 5); 4 | print("(10240<<4) + 63 >> 6: ", (10240<<4) + 63 >> 6); 5 | 6 | var j = 4; 7 | var test = 0xffffffffffffffff; 8 | print("all binary ones: ", test); 9 | 10 | print("mask with ~16: ", test & ~(1<>5; 18 | print(size); 19 | 20 | for (i=0; i0){ 17 | return new TreeNode( 18 | bottomUpTree(2*item-1, depth-1) 19 | ,bottomUpTree(2*item, depth-1) 20 | ,item 21 | ); 22 | } 23 | else { 24 | return new TreeNode(null,null,item); 25 | } 26 | } 27 | 28 | print("Expecting 0: ", bottomUpTree(0,0).itemCheck()); 29 | -------------------------------------------------------------------------------- /mongo/mongod.js: -------------------------------------------------------------------------------- 1 | var t = db.createCollection("basic2", {onDisk:false}); 2 | 3 | t.createIndex({field:1}, {name : "field", type: "art", size: 1024 * 1024}); 4 | 5 | t.save ({field:1.0, _id:"a1230"}); 6 | t.save ({field:100.0, _id:"a1231"}); 7 | t.save ({field:3.0, _id:"a1232"}); 8 | t.save ({field:300.0, _id:"a1233"}); 9 | t.save ({field:2.0, _id:"a1234"}); 10 | t.save ({field:200.0, _id:"a1235"}); 11 | 12 | var cursor1 = t.find().sort("field"); 13 | 14 | while (cursor1.hasNext()) 15 | print(cursor1.next()); 16 | 17 | var t = db.createCollection("basic3", {onDisk:false}); 18 | 19 | t.createIndex({field:1}, {name : "field", type: "art", size: 1024 * 1024}); 20 | 21 | for (var idx = 0; idx < 1000000; idx++) 22 | t.save ({field: Math.random(), _id: idx}); 23 | 24 | var cursor2 = t.find().sort("field"); 25 | 26 | while (cursor2.hasNext()) 27 | print(cursor2.next()); 28 | 29 | -------------------------------------------------------------------------------- /mongo/test_mongo.js: -------------------------------------------------------------------------------- 1 | var t = db.createCollection("basic2", {onDisk:false}); 2 | 3 | t.createIndex({field:1}, {name : "field", type: "art", size: 1024 * 1024}); 4 | 5 | t.save ({field:1.0, _id:"a1230"}); 6 | t.save ({field:100.0, _id:"a1231"}); 7 | t.save ({field:3.0, _id:"a1232"}); 8 | t.save ({field:300.0, _id:"a1233"}); 9 | t.save ({field:2.0, _id:"a1234"}); 10 | t.save ({field:200.0, _id:"a1235"}); 11 | 12 | var cursor1 = t.find().sort("field"); 13 | 14 | while (cursor1.hasNext()) 15 | print(cursor1.next()); 16 | 17 | var t = db.createCollection("basic3", {onDisk:false}); 18 | 19 | t.createIndex({field:1}, {name : "field", type: "art", size: 1024 * 1024}); 20 | 21 | for (var idx = 0; idx < 1000000; idx++) 22 | t.save ({field: Math.random(), _id: idx}); 23 | 24 | var cursor2 = t.find().sort("field"); 25 | 26 | while (cursor2.hasNext()) 27 | print(cursor2.next()); 28 | 29 | -------------------------------------------------------------------------------- /sunspider/controlflow-recursive.js: -------------------------------------------------------------------------------- 1 | // The Computer Language Shootout 2 | // http://shootout.alioth.debian.org/ 3 | // contributed by Isaac Gouy 4 | 5 | function ack(m,n){ 6 | if (m==0) { return n+1; } 7 | if (n==0) { return ack(m-1,1); } 8 | return ack(m-1, ack(m,n-1) ); 9 | } 10 | 11 | function fib(n) { 12 | if (n < 2){ return 1; } 13 | return fib(n-2) + fib(n-1); 14 | } 15 | 16 | function tak(x,y,z) { 17 | if (y >= x) return z; 18 | return tak(tak(x-1,y,z), tak(y-1,z,x), tak(z-1,x,y)); 19 | } 20 | 21 | var result = 0; 22 | 23 | for ( var i = 3; i <= 5; i++ ) { 24 | result += ack(3,i); 25 | result += fib(17.0+i); 26 | result += tak(3*i+3,2*i+2,i+1); 27 | } 28 | 29 | var expected = 57775; 30 | 31 | if (result != expected) 32 | print ("ERROR: bad result: expected ", expected, " but got ", result); 33 | else 34 | print ("OK"); 35 | 36 | -------------------------------------------------------------------------------- /js_error.h: -------------------------------------------------------------------------------- 1 | 2 | typedef enum { 3 | OK, 4 | ERROR_outofmemory, 5 | ERROR_script_internal, 6 | ERROR_script_unrecognized_function, 7 | ERROR_tcperror, 8 | ERROR_bsonformat, 9 | ERROR_notobject_or_array, 10 | ERROR_mathdomain, 11 | ERROR_endoffile, 12 | ERROR_doesnot_exist, 13 | ERROR_script_parse, 14 | ERROR_json_parse, 15 | ERROR_not_document, 16 | ERROR_not_found, 17 | ERROR_toomany_local_docstores, 18 | ERROR_txn_being_committed, 19 | ERROR_txn_not_serializable, 20 | ERROR_no_visible_version, 21 | ERROR_write_conflict, 22 | ERROR_key_constraint_violation, 23 | ERROR_not_object, 24 | ERROR_not_key, 25 | ERROR_not_operator_int, 26 | ERROR_incorrect_handle_type, 27 | ERROR_empty_argument_list, 28 | ERROR_invalid_argument, 29 | } Status; 30 | 31 | typedef void *JsStatus; 32 | 33 | // errors are values < 4096 34 | 35 | #define jsError(val) ((uint64_t)val < 0x1000 ? (uint64_t)val : 0) 36 | -------------------------------------------------------------------------------- /jsscripts/test_es6scope.js: -------------------------------------------------------------------------------- 1 | print("\n\nbegin test_es6scope.js"); 2 | print("------------------"); 3 | 4 | let x = 1; 5 | print ("x = 1: ", x); 6 | 7 | var y = 2; 8 | print ("y = 2: ", y); 9 | 10 | let z = 3; 11 | print ("z = 3: ", z); 12 | 13 | var a = 99; 14 | 15 | for (let idx = 0; idx < 5; idx++) { 16 | print ("\nLoop idx: ", idx); 17 | z = 12; 18 | print("z = 12: ", z); 19 | let a = z + idx; 20 | print("a = z + idx: ", a); 21 | print("a + z: ", a+z); 22 | } 23 | 24 | print("\nstress test of 1000000 for loop blocks"); 25 | 26 | var cnt = 0; 27 | var start = new Date(); 28 | 29 | for (let idx = 0; idx < 1000000; idx++) { 30 | let incr = idx * 2; 31 | cnt += incr; 32 | } 33 | 34 | print ("expecting total 999999000000: ", cnt); 35 | 36 | // milliseconds / 1000000 are nanoseconds 37 | 38 | var stop = new Date(); 39 | print ("nanoseconds per entry/exit: ", (stop - start)); 40 | 41 | print("\na = 99: ", a); 42 | -------------------------------------------------------------------------------- /oldjsdb/jsdb_dbpq.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | /** 4 | * data structure to be embedded in target 5 | */ 6 | 7 | typedef struct { 8 | DbAddr next; // next priority queue entry 9 | DbAddr prev; // prev priority queue entry 10 | uint64_t value; // timestamp value 11 | uint32_t set; 12 | } PQEntry; 13 | 14 | /** 15 | * doubly linked list of DbPQ::Entries 16 | */ 17 | 18 | typedef struct { 19 | uint64_t minValue; // minimum queue timestamp 20 | DbAddr queueHead; // head of the priority queue 21 | char mutex[1]; // queue manipultion lock 22 | } PQList; 23 | 24 | /* 25 | * Thread-safe bag of timestamps, with getMin() 26 | */ 27 | 28 | typedef struct { 29 | PQList entryLists[MAX_set]; // EntryList per set 30 | volatile int64_t pqTime[1]; // the priority queue timestamp 31 | uint64_t globalMin; // minimum of the EntryList minimums 32 | uint32_t cpuCount; // count of cpus 33 | char mutex[1]; // latch for computeBagMin 34 | } DbPQ; 35 | 36 | -------------------------------------------------------------------------------- /sunspider/bitops-nsieve-bits.js: -------------------------------------------------------------------------------- 1 | // The Great Computer Language Shootout 2 | // http://shootout.alioth.debian.org 3 | // 4 | // Contributed by Ian Osgood 5 | 6 | function pad(n,width) { 7 | var s = n.toString(); 8 | while (s.length < width) s = ' ' + s; 9 | return s; 10 | } 11 | 12 | function primes(m) { 13 | var i, size = m+31>>5; 14 | var isPrime = new Array(size); 15 | 16 | for (i=0; i>5] & 1<<(i&31)) { 20 | for (var j=i+i; j>5] &= ~(1<<(j&31)); 22 | 23 | highPrime = i; 24 | numPrime++; 25 | } 26 | } 27 | 28 | var highPrime = 0, numPrime = 0; 29 | 30 | primes(163840); 31 | 32 | if (highPrime != 163819) 33 | print( "ERROR: expected highPrime: ", 163819, " but got ", highPrime); 34 | else if (numPrime != 14999) 35 | print( "ERROR: expected numPrime: ", 14999, " but got ", numPrime); 36 | else 37 | print("OK"); 38 | 39 | -------------------------------------------------------------------------------- /jsscripts/test_array.js: -------------------------------------------------------------------------------- 1 | print("\n\nbegin test_array.js"); 2 | print("------------------"); 3 | var result = { 4 | version : 1, 5 | allocator : "me" 6 | }; 7 | 8 | var array = [ result, 2, "abc" ]; 9 | print("Array containing an object: ", array); 10 | 11 | var out = []; 12 | var src = [1,2,3,4,5]; 13 | 14 | for(var i = 0; i < src.length; i++) 15 | out[i] = src[i]; 16 | 17 | print("copy ", src, " to ", out); 18 | 19 | var input = "This is a test only"; 20 | var Nb = 4; 21 | 22 | var state = [[],[],[],[]]; // initialise 4xNb byte-array 'state' with input 23 | 24 | for (var i=0; i<4*Nb; i++) { 25 | print ("make entry ", i, " for '", input[i], "' at [", i%4, "][", Math.floor(i/4), "]"); 26 | state[i%4][Math.floor(i/4)] = input[i]; 27 | } 28 | 29 | print("make Two dimensional array: ", state); 30 | 31 | var t = new Array(4); 32 | 33 | for (var i=0; i<4*Nb; i++) 34 | t[i] = state[i%4][Math.floor(i/4)]; // shift into temp copy 35 | 36 | print("reduce Two dimensional array: ", t); 37 | -------------------------------------------------------------------------------- /jsscripts/test_enum.js: -------------------------------------------------------------------------------- 1 | // Options array slots 2 | 3 | var DbOptions = enum { 4 | OnDisk = 0, 5 | InitSize, 6 | UseTxn, 7 | NoDocs, 8 | DropDb, 9 | 10 | IdxKeySpec = 10, 11 | IdxKeySpecLen, // this must immediately follow 12 | IdxKeyUnique, 13 | IdxKeySparse, 14 | IdxKeyPartial, 15 | IdxKeyPartialLen, // this must immediately follow 16 | 17 | Btree1Bits = 20, // Btree1 set 18 | Btree1Xtra, 19 | MaxParam = 30 20 | }; 21 | 22 | function DbOptParse(options) { 23 | var optVals = new Array(DbOptions.MaxParam); 24 | 25 | for (var name in options) 26 | optVals[DbOptions[name]] = options[name]; 27 | 28 | return optVals; 29 | } 30 | 31 | var optobj = {OnDisk: true, InitSize: 32768}; 32 | print ("options = ", optobj); 33 | 34 | var opts = DbOptParse(optobj); 35 | print ("OnDisk (expecting true) = ", opts[DbOptions.OnDisk]); 36 | print ("InitSize (expecting 32768) = ", opts[DbOptions.InitSize]); 37 | print ("DropDb (expecting undefined) = ", opts[DbOptions.DropDb]); 38 | -------------------------------------------------------------------------------- /sunspider/bitops-nsieve-bits64.js: -------------------------------------------------------------------------------- 1 | // The Great Computer Language Shootout 2 | // http://shootout.alioth.debian.org 3 | // 4 | // Contributed by Ian Osgood 5 | // 64 bit version by Karl Malbrain 6 | 7 | function pad(n,width) { 8 | var s = n.toString(); 9 | while (s.length < width) s = ' ' + s; 10 | return s; 11 | } 12 | 13 | function primes(m) { 14 | var i, size = m+63>>6; 15 | var isPrime = new Array(size); 16 | 17 | for (i=0; i>6] & 1<<(i&63)) { 21 | for (var j=i+i; j>6] &= ~(1<<(j&63)); 23 | 24 | highPrime = i; 25 | numPrime++; 26 | } 27 | } 28 | 29 | var highPrime = 0, numPrime = 0; 30 | 31 | primes(163840); 32 | 33 | if (highPrime != 163819) 34 | print( "ERROR: expected highPrime: ", 163819, " but got ", highPrime); 35 | else if (numPrime != 14999) 36 | print( "ERROR: expected numPrime: ", 14999, " but got ", numPrime); 37 | else 38 | print("OK"); 39 | 40 | -------------------------------------------------------------------------------- /sunspider/access-nsieve.js: -------------------------------------------------------------------------------- 1 | // The Great Computer Language Shootout 2 | // http://shootout.alioth.debian.org/ 3 | // 4 | // modified by Isaac Gouy 5 | 6 | function pad(number,width){ 7 | var s = number.toString(); 8 | var prefixWidth = width - s.length; 9 | if (prefixWidth>0){ 10 | for (var i=1; i<=prefixWidth; i++) s = " " + s; 11 | } 12 | return s; 13 | } 14 | 15 | function nsieve(m, isPrime){ 16 | var i, k, count; 17 | 18 | for (i=2; i<=m; i++) { isPrime[i] = true; } 19 | count = 0; 20 | 21 | for (i=2; i<=m; i++){ 22 | if (isPrime[i]) { 23 | for (k=i+i; k<=m; k+=i) isPrime[k] = false; 24 | count++; 25 | } 26 | } 27 | return count; 28 | } 29 | 30 | function sieve() { 31 | var sum = 0; 32 | for (var i = 1; i <= 3; i++ ) { 33 | var m = (1<>6; 5 | var isPrime = new Array(size); 6 | 7 | for (i=0; i>6] & 1<<(i&63)) { 11 | for (var j=i+i; j>6] &= ~(1<<(j&63)); 13 | 14 | highPrime = i; 15 | numPrime++; 16 | } 17 | } 18 | 19 | var test = 0xffffffffffffffff; 20 | print(test); 21 | 22 | var highPrime = 0, numPrime = 0; 23 | 24 | primes(128); 25 | print(highPrime, ":", numPrime); 26 | 27 | var j = 4; 28 | print(test); 29 | test &= ~(1<<(j&63)); 30 | print(test); 31 | print(test & 1<<(j&63)); 32 | 33 | var result = new Array(5000); 34 | var sum = 0; 35 | 36 | var n = 4; 37 | var i, count = 0, m = 10000<>5; 38 | print(size); 39 | 40 | for (i=0; i>5; 5 | var isPrime = new Array(size); 6 | 7 | for (i=0; i>5]); 11 | if (isPrime[i>>5] & 1<<(i&31)) { 12 | for (var j=i+i; j>5] &= ~(1<<(j&31)); 14 | 15 | highPrime = i; 16 | numPrime++; 17 | } 18 | } 19 | 20 | var highPrime = 0, numPrime = 0; 21 | 22 | primes(128); 23 | print(highPrime, ":", numPrime); 24 | 25 | var j = 4; 26 | var test = 0xffffffffffffffff; 27 | print(test); 28 | test &= ~(1<<(j&63)); 29 | print(test); 30 | print(test & 1<<(j&63)); 31 | 32 | var result = new Array(5000); 33 | var sum = 0; 34 | 35 | var n = 4; 36 | var i, count = 0, m = 10000<>5; 37 | print(size); 38 | 39 | for (i=0; i> ((b << 1) & 14)); 10 | c += 3 & (bi3b >> ((b >> 2) & 14)); 11 | c += 3 & (bi3b >> ((b >> 5) & 6)); 12 | return c; 13 | 14 | /* 15 | lir4,0xE994; 9 instructions, no memory access, minimal register dependence, 6 shifts, 2 adds, 1 inline assign 16 | rlwinmr5,r3,1,28,30 17 | rlwinmr6,r3,30,28,30 18 | rlwinmr7,r3,27,29,30 19 | rlwnmr8,r4,r5,30,31 20 | rlwnmr9,r4,r6,30,31 21 | rlwnmr10,r4,r7,30,31 22 | addr3,r8,r9 23 | addr3,r3,r10 24 | */ 25 | } 26 | 27 | 28 | function TimeFunc(func) { 29 | var x, y, t; 30 | var sum = 0; 31 | for(var x=0; x<500; x++) 32 | for(var y=0; y<256; y++) sum += func(y); 33 | return sum; 34 | } 35 | 36 | var sum = TimeFunc(fast3bitlookup); 37 | 38 | var expected = 512000; 39 | if (sum != expected) 40 | print( "ERROR: bad result: expected ", expected, " but got ", sum); 41 | else 42 | print( "OK"); 43 | 44 | 45 | -------------------------------------------------------------------------------- /jsscripts/test_db.js: -------------------------------------------------------------------------------- 1 | print("\n\nbegin test_db.js"); 2 | print("------------------"); 3 | 4 | var db, dbname; 5 | 6 | for (dbname in catalog.db) 7 | db = new Db(dbname), db.drop(); 8 | 9 | var dbops = {onDisk:true}; 10 | var doc, cnt; 11 | 12 | db = new Db("testing", dbops); 13 | 14 | print("Handle for: ", db); 15 | 16 | var store = db.createDocStore("docStore", {onDisk:true}); 17 | 18 | print("Handle for: ", store); 19 | 20 | doc = store.insert({a:1, b:2, c: {d:"A", e:"F"}}); 21 | 22 | print("recordId for insert: ", doc.docId); 23 | 24 | var iterator = store.createIterator(); 25 | 26 | print("Handle for: ", iterator); 27 | 28 | print("\nPrint(doc) Expecting {a:1, b:2, c: {d:\"A\", e:\"F\"}} : ", doc); 29 | print("\nPrint(doc.c) Expecting {d:\"A\", e:\"F\"} : ", doc.c); 30 | 31 | print ("\nIterate forwards"); 32 | 33 | iterator.seek(IteratorOp.opBegin); 34 | 35 | for (cnt = 0; doc = iterator.next(); cnt++) 36 | print("DocId: ", doc.docId, " -> ", doc); 37 | 38 | print (cnt, " found forwards"); 39 | 40 | print ("\nIterate backwards"); 41 | 42 | for (cnt = 0; doc = iterator.prev(); cnt++) 43 | print("DocId: ", doc.docId, " -> ", doc); 44 | 45 | print (cnt, " found backwards"); 46 | -------------------------------------------------------------------------------- /js_vector.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // API 4 | 5 | #define vec_free(a) ((a) ? js_free(vec_raw(a)),0 : 0) 6 | #define vec_push(a,v) (vec_maybegrow(a,1), (a)[vec_size(a)++] = (v)) 7 | #define vec_pop(a) ((a)[--vec_size(a)]) 8 | #define vec_cnt(a) ((a) ? vec_size(a) : 0) 9 | #define vec_max(a) ((a) ? vec_cap(a) : 0) 10 | #define vec_add(a,n) (vec_maybegrow(a,n), vec_size(a)+=(n)) 11 | #define vec_last(a) ((a)[vec_size(a)-1]) 12 | 13 | // access with a[i] 14 | 15 | // internal 16 | 17 | #define vec_raw(a) (((uint32_t *) (a)) - 2) 18 | #define vec_cap(a) vec_raw(a)[0] // maximum capacity 19 | #define vec_size(a) vec_raw(a)[1] // current size 20 | 21 | #define vec_needgrow(a,n) ((a)==0 || vec_size(a)+(n) > vec_cap(a)) 22 | #define vec_maybegrow(a,n) (vec_needgrow((a),(n)) ? ((a) = vec_grow((a), (n), sizeof(*(a)), 0)) : 0) 23 | #define vec_slice(a,q) vec_sliceqty((a), (q), sizeof(*(a))) 24 | 25 | void *vec_grow(void *vector, uint32_t increment, uint32_t itemsize, bool map); 26 | void *vec_sliceqty(void *vector, uint32_t qty, uint32_t itemsize); 27 | void *vec_dup(void *vector); 28 | 29 | #define newVector(numitems,itemsize,map) (vec_grow(NULL, numitems, itemsize, map)) 30 | -------------------------------------------------------------------------------- /data/c-skel.m4: -------------------------------------------------------------------------------- 1 | -*- Autoconf -*- 2 | 3 | # C skeleton dispatching for Bison. 4 | 5 | # Copyright (C) 2006-2007, 2009-2013 Free Software Foundation, Inc. 6 | 7 | # This program is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # This program is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with this program. If not, see . 19 | 20 | b4_glr_if( [m4_define([b4_used_skeleton], [b4_pkgdatadir/[glr.c]])]) 21 | b4_nondeterministic_if([m4_define([b4_used_skeleton], [b4_pkgdatadir/[glr.c]])]) 22 | 23 | m4_define_default([b4_used_skeleton], [b4_pkgdatadir/[yacc.c]]) 24 | m4_define_default([b4_skeleton], ["b4_basename(b4_used_skeleton)"]) 25 | 26 | m4_include(b4_used_skeleton) 27 | -------------------------------------------------------------------------------- /data/c++-skel.m4: -------------------------------------------------------------------------------- 1 | -*- Autoconf -*- 2 | 3 | # C++ skeleton dispatching for Bison. 4 | 5 | # Copyright (C) 2006-2007, 2009-2013 Free Software Foundation, Inc. 6 | 7 | # This program is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # This program is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with this program. If not, see . 19 | 20 | b4_glr_if( [m4_define([b4_used_skeleton], [b4_pkgdatadir/[glr.cc]])]) 21 | b4_nondeterministic_if([m4_define([b4_used_skeleton], [b4_pkgdatadir/[glr.cc]])]) 22 | 23 | m4_define_default([b4_used_skeleton], [b4_pkgdatadir/[lalr1.cc]]) 24 | m4_define_default([b4_skeleton], ["b4_basename(b4_used_skeleton)"]) 25 | 26 | m4_include(b4_used_skeleton) 27 | -------------------------------------------------------------------------------- /data/java-skel.m4: -------------------------------------------------------------------------------- 1 | -*- Autoconf -*- 2 | 3 | # Java skeleton dispatching for Bison. 4 | 5 | # Copyright (C) 2007, 2009-2013 Free Software Foundation, Inc. 6 | 7 | # This program is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # This program is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with this program. If not, see . 19 | 20 | b4_glr_if( [b4_complain([%%glr-parser not supported for Java])]) 21 | b4_nondeterministic_if([b4_complain([%%nondeterministic-parser not supported for Java])]) 22 | 23 | m4_define_default([b4_used_skeleton], [b4_pkgdatadir/[lalr1.java]]) 24 | m4_define_default([b4_skeleton], ["b4_basename(b4_used_skeleton)"]) 25 | 26 | m4_include(b4_used_skeleton) 27 | -------------------------------------------------------------------------------- /sunspider/math-spectral-norm.js: -------------------------------------------------------------------------------- 1 | // The Great Computer Language Shootout 2 | // http://shootout.alioth.debian.org/ 3 | // 4 | // contributed by Ian Osgood 5 | 6 | jsdb_setOption("Math"); 7 | 8 | function A(i,j) { 9 | return 1/((i+j)*(i+j+1)/2+i+1); 10 | } 11 | 12 | function Au(u,v) { 13 | for (var i=0; i0){ 14 | return new TreeNode( 15 | bottomUpTree(2*item-1, depth-1) 16 | ,bottomUpTree(2*item, depth-1) 17 | ,item 18 | ); 19 | } 20 | else { 21 | return new TreeNode(null,null,item); 22 | } 23 | } 24 | 25 | var ret; 26 | 27 | for ( var n = 4; n <= 7; n += 1 ) { 28 | var minDepth = 4; 29 | var maxDepth = Math.max(minDepth + 2, n); 30 | var stretchDepth = maxDepth + 1; 31 | 32 | var check = bottomUpTree(0,stretchDepth).itemCheck(); 33 | 34 | var longLivedTree = bottomUpTree(0,maxDepth); 35 | for (var depth=minDepth; depth<=maxDepth; depth+=2){ 36 | var iterations = 1 << (maxDepth - depth + minDepth); 37 | 38 | check = 0; 39 | for (var i=1; i<=iterations; i++){ 40 | check += bottomUpTree(i,depth).itemCheck(); 41 | check += bottomUpTree(-i,depth).itemCheck(); 42 | } 43 | } 44 | 45 | print("level ", n, " check = ", longLivedTree.itemCheck()); 46 | } 47 | 48 | 49 | -------------------------------------------------------------------------------- /jsscripts/test_xtn.js: -------------------------------------------------------------------------------- 1 | print("\n\nbegin test_xtn.js"); 2 | print("------------------"); 3 | Object.extend = function(destination, source) { 4 | for (var property in source) { 5 | destination[property] = source[property]; 6 | } 7 | return destination; 8 | }; 9 | 10 | 11 | var Class = { 12 | create: function() { 13 | return function() { 14 | this.init.apply(this, arguments); 15 | }; 16 | } 17 | }; 18 | 19 | print("make material"); 20 | var material = {}; 21 | 22 | print("make material.BaseMaterial"); 23 | material.BaseMaterial = Class.create(); 24 | 25 | print("set material.BaseMaterial.prototype"); 26 | material.BaseMaterial.prototype = { 27 | test:2, 28 | init: function() {}, 29 | getColor: function(u,v) {} 30 | }; 31 | 32 | print(material.BaseMaterial.prototype); 33 | 34 | var tst = new material.BaseMaterial(); 35 | 36 | print("make material.solid"); 37 | material.solid = Class.create(); 38 | print("made material.solid"); 39 | 40 | material.solid.prototype = Object.extend( 41 | new material.BaseMaterial(), { 42 | init: function(color, refl, refr, trans, gloss) { 43 | this.color = color; 44 | this.reflection = refl; 45 | this.transparency = trans; 46 | this.gloss = gloss; 47 | this.hasTexture = false; 48 | }, 49 | getColor: function(u,v) {return this.color;}, 50 | toString: function() {return Object.prototype.toString(this);} 51 | } 52 | ); 53 | 54 | print("material.solid.prototype: ", material.solid.prototype); 55 | -------------------------------------------------------------------------------- /jsscripts/test_bin.js: -------------------------------------------------------------------------------- 1 | print("\n\nbegin test_bin.js"); 2 | print("------------------"); 3 | function TreeNode(left,right,item){ 4 | this.left = left; 5 | this.right = right; 6 | this.item = item; 7 | } 8 | 9 | TreeNode.prototype.itemCheck = function(){ 10 | if (this.left==null) return this.item; 11 | else return this.item + this.left.itemCheck() - this.right.itemCheck(); 12 | }; 13 | 14 | function bottomUpTree(item,depth){ 15 | if (depth>0){ 16 | return new TreeNode( 17 | bottomUpTree(2*item-1, depth-1) 18 | ,bottomUpTree(2*item, depth-1) 19 | ,item 20 | ); 21 | } 22 | else { 23 | return new TreeNode(null,null,item); 24 | } 25 | } 26 | 27 | var ret; 28 | print("GO"); 29 | 30 | for ( var n = 4; n <= 7; n += 1 ) { 31 | var minDepth = 4; 32 | var maxDepth = Math.max(minDepth + 2, n); 33 | var stretchDepth = maxDepth + 1; 34 | 35 | var check = bottomUpTree(0,stretchDepth).itemCheck(); 36 | 37 | var longLivedTree = bottomUpTree(0,maxDepth); 38 | for (var depth=minDepth; depth<=maxDepth; depth+=2){ 39 | var iterations = 1 << (maxDepth - depth + minDepth); 40 | 41 | check = 0; 42 | for (var i=1; i<=iterations; i++){ 43 | check += bottomUpTree(i,depth).itemCheck(); 44 | check += bottomUpTree(-i,depth).itemCheck(); 45 | } 46 | } 47 | 48 | print("level ", n, " check = ", longLivedTree.itemCheck()); 49 | } 50 | 51 | 52 | -------------------------------------------------------------------------------- /jsscripts/test_props.js: -------------------------------------------------------------------------------- 1 | print("\n\nbegin test_props.js"); 2 | print("------------------"); 3 | var str = "Length of a short string "; 4 | var num = 300; 5 | 6 | print ("string: '", str, "'"); 7 | print ("length: ", "'", str.length, "'"); 8 | print ("charAt 2: ", "'", str.charAt(2), "'"); 9 | print ("concat a,2,3: ", "'", str.concat("a",2,3), "'"); 10 | print ("endsWith space: ", "'", str.endsWith(" "), "'"); 11 | print ("includes th: ", "'", str.includes("th"), "'"); 12 | print ("includes tx: ", "'", str.includes("tx"), "'"); 13 | print ("indexOf th: ", "'", str.indexOf("th"), "'"); 14 | print ("lastIndexOf g: ", "'", str.lastIndexOf("g"), "'"); 15 | print ("replaceAll g w/xx: ", "'", str.replaceAll("g", "xx"), "'"); 16 | print ("replace g w/xx: ", "'", str.replace("g", "xx"), "'"); 17 | print ("slice 1: ", "'", str.slice(1), "'"); 18 | print ("slice -4: ", "'", str.slice(-4), "'"); 19 | print ("split: ", "'", str.split(" "), "'"); 20 | print ("startsWith of: ", "'", str.startsWith("of", 7), "'"); 21 | print ("startsWith of: ", "'", str.startsWith("of", 6), "'"); 22 | print ("substr 6: ", "'", str.substr(6), "'"); 23 | print ("substr 6,3: ", "'", str.substr(6, 3), "'"); 24 | print ("subString 6: ", "'", str.substring(6), "'"); 25 | print ("toLowerCast: ", "'", str.toLowerCase(), "'"); 26 | print ("toUpperCase: ", "'", str.toUpperCase(), "'"); 27 | print ("trim: ", "'", str.trim(), "'"); 28 | print ("toExponential 300: ", "'", num.toExponential(2), "'"); 29 | print ("toString 300: ", "'", num.toString(), "'"); 30 | -------------------------------------------------------------------------------- /sunspider/math-partial-sums.js: -------------------------------------------------------------------------------- 1 | // The Computer Language Shootout 2 | // http://shootout.alioth.debian.org/ 3 | // contributed by Isaac Gouy 4 | 5 | jsdb_setOption("Math"); 6 | 7 | function partial(n){ 8 | var a1 = 0; 9 | var a2 = 0; 10 | var a3 = 0; 11 | var a4 = 0; 12 | var a5 = 0; 13 | var a6 = 0; 14 | var a7 = 0; 15 | var a8 = 0; 16 | var a9 = 0; 17 | 18 | var twothirds = 2.0/3.0; 19 | var alt = -1.0; 20 | var k2 = 0; 21 | var k3 = 0; 22 | var sk = 0; 23 | var ck = 0; 24 | 25 | for (var k = 1; k <= n; k++){ 26 | k2 = k*k; 27 | k3 = k2*k; 28 | sk = Math.sin(k); 29 | ck = Math.cos(k); 30 | alt = -alt; 31 | 32 | a1 += Math.pow(twothirds,k-1); 33 | a2 += Math.pow(k,-0.5); 34 | a3 += 1.0/(k*(k+1.0)); 35 | a4 += 1.0/(k3 * sk*sk); 36 | a5 += 1.0/(k3 * ck*ck); 37 | a6 += 1.0/k; 38 | a7 += 1.0/k2; 39 | a8 += alt/k; 40 | a9 += alt/(2*k -1); 41 | } 42 | 43 | // NOTE: We don't try to validate anything from pow(), sin() or cos() because those aren't 44 | // well-specified in ECMAScript. 45 | return a6 + a7 + a8 + a9; 46 | } 47 | 48 | var total = 0; 49 | 50 | for (var i = 1024; i <= 16384; i *= 2) { 51 | total += partial(i); 52 | } 53 | 54 | var expected = 60.08994194659945; 55 | 56 | if (total != expected) 57 | print( "ERROR: bad result: expected ", expected, " but got ", total); 58 | else 59 | print ("OK"); 60 | 61 | -------------------------------------------------------------------------------- /oldjsdb/jsdb_dbbtreeindex.c: -------------------------------------------------------------------------------- 1 | #include "jsdb.h" 2 | #include "jsdb_db.h" 3 | 4 | bool btreeindex_hasdup (DbMap *index, DbAddr *base, uint8_t *suffix) { 5 | 6 | return false; 7 | } 8 | 9 | Status btreeIndexKey (DbMap *index, DbDoc *doc, DocId docId) { 10 | BtreeIndex *btree = btreeIndex(index); 11 | uint8_t buff[MAX_key], *keys; 12 | uint32_t off = 0, size = 0; 13 | KeySuffix *suffix; 14 | IndexKey *key; 15 | value_t field; 16 | int fldLen; 17 | 18 | keys = getObj(index, btree->index->keys); 19 | key = (IndexKey *)keys; 20 | 21 | // add each key field to the Btree key 22 | 23 | while (key->type != key_end) { 24 | uint8_t next[MAX_key]; 25 | value_t name; 26 | 27 | name.bits = vt_string; 28 | name.str = key->name; 29 | name.aux = key->len; 30 | 31 | field = lookupDoc((document_t *)(doc + 1), name); 32 | fldLen = keyFld(field, key, next, MAX_key - size); 33 | 34 | if (fldLen < 0) 35 | return ERROR_keytoolong; 36 | 37 | if (fldLen < 128) 38 | buff[size++] = fldLen; 39 | else 40 | buff[size++] = fldLen/256 | 0x80, buff[size++] = fldLen; 41 | 42 | memcpy (buff + size, next, fldLen); 43 | size += fldLen; 44 | 45 | off += sizeof(IndexKey) + key->len; 46 | key = (IndexKey *)(keys + off); 47 | } 48 | 49 | if (!size) 50 | return OK; 51 | 52 | buff[size++] = 0; // mark last key field 53 | suffix = (KeySuffix *)(buff + size); 54 | store64(suffix->docId, docId.bits); 55 | size += sizeof(KeySuffix); 56 | 57 | return btreeInsertKey(index, buff, size, 0, Btree_indexed); 58 | } 59 | 60 | -------------------------------------------------------------------------------- /javascript-database.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.28010.2003 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "javascript-database", "javascript-database.vcxproj", "{F0D4248A-67E2-40D1-990E-0BB66AFB4325}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|x64 = Debug|x64 11 | Debug|x86 = Debug|x86 12 | Release|x64 = Release|x64 13 | Release|x86 = Release|x86 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {F0D4248A-67E2-40D1-990E-0BB66AFB4325}.Debug|x64.ActiveCfg = Debug|x64 17 | {F0D4248A-67E2-40D1-990E-0BB66AFB4325}.Debug|x64.Build.0 = Debug|x64 18 | {F0D4248A-67E2-40D1-990E-0BB66AFB4325}.Debug|x86.ActiveCfg = Debug|Win32 19 | {F0D4248A-67E2-40D1-990E-0BB66AFB4325}.Debug|x86.Build.0 = Debug|Win32 20 | {F0D4248A-67E2-40D1-990E-0BB66AFB4325}.Release|x64.ActiveCfg = Release|x64 21 | {F0D4248A-67E2-40D1-990E-0BB66AFB4325}.Release|x64.Build.0 = Release|x64 22 | {F0D4248A-67E2-40D1-990E-0BB66AFB4325}.Release|x86.ActiveCfg = Release|Win32 23 | {F0D4248A-67E2-40D1-990E-0BB66AFB4325}.Release|x86.Build.0 = Release|Win32 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | GlobalSection(ExtensibilityGlobals) = postSolution 29 | SolutionGuid = {0415502C-6FD8-4934-AF93-446C742A6D80} 30 | EndGlobalSection 31 | EndGlobal 32 | -------------------------------------------------------------------------------- /oldjsdb/jsdb_util.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define MUTEX_BIT 0x1 4 | #define DEAD_BIT 0x2 5 | 6 | #ifdef _WIN32 7 | #define WIN32_LEAN_AND_MEAN 8 | #include 9 | #else 10 | #define relax() asm volatile("pause\n" : : : "memory") 11 | #endif 12 | 13 | /** 14 | * spin latches 15 | */ 16 | 17 | void lockLatch(volatile char* latch); 18 | void unlockLatch(volatile char* latch); 19 | void waitNonZero(volatile char *zero); 20 | void art_yield(); 21 | 22 | /** 23 | * atomic integer ops 24 | */ 25 | 26 | void kill_slot(volatile char* latch); 27 | 28 | int64_t atomicAdd64(volatile int64_t *value, int64_t amt); 29 | int32_t atomicAdd32(volatile int32_t *value, int32_t amt); 30 | int64_t atomicOr64(volatile int64_t *value, int64_t amt); 31 | int32_t atomicOr32(volatile int32_t *value, int32_t amt); 32 | uint64_t compareAndSwap(uint64_t* target, uint64_t compare_val, uint64_t swap_val); 33 | 34 | /** 35 | * memory mapping 36 | */ 37 | 38 | void* mapMemory(DbMap *map, uint64_t offset, uint64_t size, uint32_t segNo); 39 | void unmapSeg(DbMap *map, uint32_t segNo); 40 | bool mapSeg(DbMap *map, uint32_t segNo); 41 | 42 | /** 43 | * interface to 'rdtscp', when available 44 | */ 45 | 46 | uint32_t getCpuCount(); 47 | uint32_t getSet(); 48 | 49 | /** 50 | * file system lock 51 | */ 52 | 53 | #ifdef _WIN32 54 | void lockArena(HANDLE hndl, char *fName); 55 | void unlockArena(HANDLE hndl, char *fName); 56 | #else 57 | void lockArena(int hndl, char *fName); 58 | void unlockArena(int hndl, char *fName); 59 | #endif 60 | 61 | bool fileExists(char *path); 62 | -------------------------------------------------------------------------------- /systemBase.js: -------------------------------------------------------------------------------- 1 | var builtins = enum { 2 | builtinStr, 3 | builtinObj, 4 | builtinArray, 5 | builtinNum, 6 | builtinBool, 7 | builtinDate, 8 | builtinFcn, 9 | builtinDoc, 10 | builtinDocId, 11 | builtinKey, 12 | builtinCatalog, 13 | builtinDb, 14 | builtinStore, 15 | builtinIndex, 16 | builtinCursor, 17 | builtinIter, 18 | builtinTxn 19 | }; 20 | 21 | var _values = enum { 22 | vt_undef = 0, 23 | vt_bool, 24 | vt_int, 25 | vt_dbl, 26 | vt_date, 27 | vt_infinite, 28 | vt_number, 29 | vt_string, 30 | vt_nan, 31 | vt_null, 32 | vt_file, 33 | vt_status, 34 | vt_control, 35 | vt_closure, 36 | vt_endlist, 37 | vt_document, 38 | vt_docId, 39 | vt_txnId, // 64 bit immediate 40 | vt_lval, 41 | vt_centi, 42 | vt_array, 43 | vt_object, 44 | vt_binary, 45 | vt_function, 46 | vt_symbol, 47 | vt_uuid, // 16 byte string 48 | vt_md5, 49 | vt_propfcn, 50 | vt_propval, 51 | vt_weakref, 52 | vt_hndl, 53 | vt_key, 54 | vt_MAX 55 | }; 56 | 57 | function Object() { 58 | var ans; 59 | 60 | if(this) 61 | ans = this; 62 | else 63 | ans = {}; 64 | 65 | if (arguments.length > 0) 66 | ans.setValue(arguments[0]); 67 | 68 | return ans; 69 | } 70 | 71 | jsdb_installProps(Object, builtins.builtinObj, _values.vt_object); 72 | 73 | Object.assign = function() { 74 | var target, names, values; 75 | 76 | if (arguments.length < 1) 77 | return {}; 78 | 79 | target = arguments[0]; 80 | 81 | if (typeof target == "object") 82 | for (var i = 1; i < arguments.length; i++) 83 | for (var key in arguments[i]) 84 | target[key] = arguments[i][key]; 85 | 86 | return target; 87 | }; 88 | -------------------------------------------------------------------------------- /jsscripts/test_json.js: -------------------------------------------------------------------------------- 1 | print("\n\nbegin test_json.js"); 2 | print("------------------"); 3 | var x = 1; 4 | 5 | function test(a) { 6 | return function () { return a++ + x++;}; 7 | } 8 | var func = test(2); 9 | 10 | print (func()); 11 | print (func()); 12 | 13 | var k = '{"a":1,"b":"4","c":{"d":4.5}}'; 14 | var p = JSON.parse(k); 15 | print("Parse of <", k, ">\nis ", p, "\n"); 16 | 17 | k = '{"a":[1,2,3,true,false,null],"b":"4","c":{"b":4.5.5}}'; 18 | p = JSON.parse(k); 19 | print("Parse of <", k, ">\nis ", p, "\n"); 20 | 21 | var j = {a:[1,2,3,true,false,null],b:4,c:{b:4.5E-1, d:1/0, e:-1/0}}; 22 | var txt = JSON.stringify(j); 23 | print("stringify of <", j, ">\nis ", txt); 24 | p = JSON.parse(txt); 25 | print("and reparse is <", p, ">\n"); 26 | 27 | j = {a:[],b:4,c:{d:5}}; 28 | txt = JSON.stringify(j); 29 | print("stringify of <", j, ">\nis ", txt); 30 | p = JSON.parse(txt); 31 | print("and reparse is <", p, ">\n"); 32 | 33 | print ("property j.c.d = ", j.c.d); 34 | 35 | j = [[1,2,3]]; 36 | txt = JSON.stringify(j); 37 | print("stringify of <", j, ">\nis ", txt); 38 | p = JSON.parse(txt); 39 | print("and reparse is <", p, ">\n"); 40 | 41 | j = [[1,2,3,["a", "b"]], "done"]; 42 | txt = JSON.stringify(j); 43 | print("stringify of <", j, ">\nis ", txt); 44 | p = JSON.parse(txt); 45 | print("and reparse is <", p, ">\n"); 46 | 47 | j = [["a","b","c"]]; 48 | txt = JSON.stringify(j); 49 | print("stringify of <", j, ">\nis ", txt); 50 | p = JSON.parse(txt); 51 | print("and reparse is <", p, ">\n"); 52 | 53 | var buff = "print(arguments);"; 54 | jsdb_parseEval("TestPgm", buff, ["abc",3]); 55 | 56 | buff = "print(func());"; 57 | jsdb_parseEval("TestPgm", buff, ["abc"]); 58 | 59 | -------------------------------------------------------------------------------- /jsscripts/test_dbartree.js: -------------------------------------------------------------------------------- 1 | print("\n\nbegin test_dbartree.js"); 2 | print("------------------"); 3 | 4 | var db, dbname; 5 | 6 | for (dbname in catalog.db) 7 | db = new Db(dbname), db.drop(); 8 | 9 | var dbops = {onDisk:true}; 10 | db = new Db("testing", dbops); 11 | 12 | var store = db.createDocStore("artree", {onDisk:true}); 13 | 14 | var PrimaryIdx = store.createIndex("PrimaryArtree1", {idxType:HndlType.ArtIndex, onDisk:true}, {field:"fwd:dbl"}); 15 | 16 | store.insert ({field:1.0, _id:"a1230"}); 17 | store.insert ({field:100.0, _id:"a1231"}); 18 | store.insert ({field:3.0, _id:"a1232"}); 19 | store.insert ({field:300.0, _id:"a1233"}); 20 | store.insert ({field:2.0, _id:"a1234"}); 21 | store.insert ({field:200.0, _id:"a1235"}); 22 | 23 | var cursor1 = PrimaryIdx.createCursor({deDup:true}); 24 | var doc; 25 | 26 | while (doc = cursor1.move(CursorOp.opNext)) 27 | print(doc); 28 | 29 | var store = db.createDocStore("artree3", {onDisk:true}); 30 | 31 | var PrimaryIdx = store.createIndex("PrimaryArtree2", {idxType:HndlType.ArtIndex, onDisk:true}, {field:"fwd:dbl"}); 32 | 33 | print("begin insert of 1M documents with random field arttree index"); 34 | var start = Date(); 35 | 36 | for (var idx = 0; idx < 1000000; idx++) 37 | store.insert ({field: Math.random(), _id: idx}); 38 | 39 | print("elapsed time: ", (Date() - start)/1000., " seconds"); 40 | 41 | print("\nbegin cursor check of 1M documents with random field arttree index"); 42 | 43 | var cursor2 = PrimaryIdx.createCursor(); 44 | 45 | start = Date(); 46 | var prev = 0.0; 47 | var cnt = 0; 48 | 49 | while (doc = cursor2.move(CursorOp.opNext)) { 50 | if (doc.field < prev) 51 | print(prev, "==>", doc.field); 52 | prev = doc.field; 53 | cnt++; 54 | } 55 | 56 | print("elapsed time: ", (Date() - start)/1000., " seconds"); 57 | print("end cursor check of ", cnt, " documents with random field arttree index"); 58 | -------------------------------------------------------------------------------- /jsscripts/test_dbbtree.js: -------------------------------------------------------------------------------- 1 | print("\n\nbegin test_dbbtree.js"); 2 | print("------------------"); 3 | 4 | var db, dbname; 5 | 6 | for (dbname in catalog.db) 7 | db = new Db(dbname), db.drop(); 8 | 9 | var dbops = {onDisk:true}; 10 | db = new Db("testing", dbops); 11 | 12 | var store = db.createDocStore("btree2", {onDisk:true}); 13 | 14 | var PrimaryIdx = store.createIndex("PrimaryBtree1", {idxType:HndlType.Btree1Index, onDisk:true}, {field:"fwd:dbl"}); 15 | 16 | store.insert ({field:1.0, _id:"a1230"}); 17 | store.insert ({field:100.0, _id:"a1231"}); 18 | store.insert ({field:3.0, _id:"a1232"}); 19 | store.insert ({field:300.0, _id:"a1233"}); 20 | store.insert ({field:2.0, _id:"a1234"}); 21 | store.insert ({field:200.0, _id:"a1235"}); 22 | 23 | var cursor1 = PrimaryIdx.createCursor({deDup:true}); 24 | var doc; 25 | 26 | while (doc = cursor1.move(CursorOp.opNext)) 27 | print(doc); 28 | 29 | var store = db.createDocStore("btree3", {onDisk:true}); 30 | 31 | var PrimaryIdx = store.createIndex("PrimaryBtree2", {idxType:HndlType.Btree1Index, onDisk:true}, {field:"fwd:dbl"}); 32 | 33 | var start = Date(); 34 | 35 | print("begin insert of 1M documents with random field btree index"); 36 | 37 | for (var idx = 0; idx < 1000000; idx++) 38 | store.insert ({field: Math.random(), _id: idx}); 39 | 40 | print("elapsed time: ", (Date() - start)/1000., " seconds"); 41 | 42 | print("\nbegin cursor check of 1M documents with random field btree index"); 43 | 44 | var cursor2 = PrimaryIdx.createCursor(); 45 | 46 | var prev = 0.0; 47 | var cnt = 0; 48 | start = Date(); 49 | 50 | while (doc = cursor2.move(CursorOp.opNext)) { 51 | if (doc.field < prev) 52 | print(prev, "==>", doc.field); 53 | prev = doc.field; 54 | cnt++; 55 | } 56 | 57 | print("elapsed time: ", (Date() - start)/1000., " seconds"); 58 | print("end cursor check of ", cnt, " documents with random field btree index"); 59 | 60 | -------------------------------------------------------------------------------- /js_error.c: -------------------------------------------------------------------------------- 1 | #include "js.h" 2 | 3 | char *strstatus(Status s) { 4 | switch (s) { 5 | case OK: return "OK"; 6 | case ERROR_outofmemory: return "out of memory"; 7 | case ERROR_script_internal: return "script internal error"; 8 | case ERROR_script_unrecognized_function: return "script unrecognized function"; 9 | case ERROR_tcperror: return "tcperror"; 10 | case ERROR_bsonformat: return "bsonformat"; 11 | case ERROR_notobject_or_array: return "not object or array"; 12 | case ERROR_mathdomain: return "outside math domain"; 13 | case ERROR_endoffile: return "end of file"; 14 | case ERROR_doesnot_exist: return "does not exist"; 15 | case ERROR_script_parse: return "script parse"; 16 | case ERROR_json_parse: return "json parse"; 17 | case ERROR_not_document: return "not document"; 18 | case ERROR_not_found: return "not found"; 19 | case ERROR_toomany_local_docstores: return "too many docStores"; 20 | case ERROR_txn_being_committed: return "txn being committed"; 21 | case ERROR_no_visible_version: return "no visible version"; 22 | case ERROR_write_conflict: return "write conflict"; 23 | case ERROR_key_constraint_violation:return "key constraint violation"; 24 | case ERROR_not_operator_int: return "Invalid iterator seek operation"; 25 | case ERROR_not_key: return "not key value"; 26 | default:; 27 | } 28 | return NULL; 29 | } 30 | 31 | void errorText(Status s) { 32 | char *status = strstatus(s); 33 | 34 | if (!s) 35 | printf("Status: OK\n"); 36 | else if (status) 37 | printf("Error: %s\n", status); 38 | else 39 | printf("Unrecognized error: %d", s); 40 | } 41 | 42 | value_t makeError(Node *node, environment_t *env, char *msg) { 43 | value_t v; 44 | 45 | fprintf (stderr, "js error %s line = %d, node id = %d type = %d: %s\n", env->first->script, (int)node->lineNo, (int)(node - env->table), (int)node->type, msg); 46 | 47 | v.bits = vt_control; 48 | return v; 49 | } 50 | -------------------------------------------------------------------------------- /js_dbindex.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // maximum number of nested array fields in an index key 4 | 5 | #define MAX_array_fields 8 6 | #define INT_key 12 // max extra bytes store64 creates 7 | 8 | typedef union { 9 | char charVal; 10 | bool boolVal; 11 | short shortVal; 12 | int intVal; 13 | int64_t longVal; 14 | float floatVal; 15 | double dblVal; 16 | char strVal[1]; 17 | } KeyVal; 18 | 19 | typedef enum { 20 | key_undef = 0, 21 | key_bool, 22 | key_int, 23 | key_dbl, 24 | key_str, 25 | key_mask = 7, 26 | key_first = 8, 27 | key_reverse = 16 28 | } KeyType; 29 | 30 | // one Key field specification 31 | // with nested field names 32 | // for compound object lookup 33 | 34 | typedef struct { 35 | uint8_t numFlds; // number of compound field names present 36 | uint8_t fldType; // type of field 37 | 38 | // field element array 39 | // field name bytes follow 40 | 41 | struct Field { 42 | uint64_t hash; // field name hash value 43 | uint32_t len[1]; // length of field name 44 | uint8_t name[1]; // field name 45 | } field; 46 | } KeySpec; 47 | 48 | typedef struct { 49 | uint16_t keyLen; // size of key at this step 50 | uint16_t off; // offset of the IndexKey 51 | uint16_t cnt; // size of array 52 | uint16_t idx; // next idx 53 | value_t *values; // array vals 54 | } KeyStack; 55 | 56 | value_t js_closeHandle(uint32_t args, environment_t *env); 57 | void js_deleteHandle(value_t hndl); 58 | 59 | DbAddr compileKey(Handle *docHndl, value_t spec); 60 | 61 | DbStatus addKeyField(DbHandle* idxHndl, KeySpec* spec, 62 | struct Field* field); 63 | uint16_t appendKeyField(Handle* idxHndls, KeySpec* spec, 64 | struct Field* field, uint8_t* keyDest, uint16_t keyRoom, 65 | void* cbEnv); 66 | DbStatus installKey(KeyValue * keyValue, ObjId * docId, Handle * docHndl, Handle * idxHndl); 67 | DbStatus idxBldKeyHelper(value_t baseArg, ObjId *docId, Handle *docHndl, Handle *idxHndl, value_t *keys); 68 | -------------------------------------------------------------------------------- /sunspider/access-fannkuch.js: -------------------------------------------------------------------------------- 1 | /* The Great Computer Language Shootout 2 | http://shootout.alioth.debian.org/ 3 | contributed by Isaac Gouy */ 4 | 5 | function fannkuch(n) { 6 | var check = 0; 7 | var perm = Array(n); 8 | var perm1 = Array(n); 9 | var count = Array(n); 10 | var maxPerm = Array(n); 11 | var maxFlipsCount = 0; 12 | var m = n - 1; 13 | 14 | for (var i = 0; i < n; i++) perm1[i] = i; 15 | var r = n; 16 | 17 | while (true) { 18 | // write-out the first 30 permutations 19 | if (check < 30){ 20 | var s = ""; 21 | for(var i=0; i> 1; 34 | for (var i = 0; i < k2; i++) { 35 | var temp = perm[i]; perm[i] = perm[k - i]; perm[k - i] = temp; 36 | } 37 | flipsCount++; 38 | } 39 | 40 | if (flipsCount > maxFlipsCount) { 41 | maxFlipsCount = flipsCount; 42 | for (var i = 0; i < n; i++) maxPerm[i] = perm1[i]; 43 | } 44 | } 45 | 46 | while (true) { 47 | if (r == n) return maxFlipsCount; 48 | var perm0 = perm1[0]; 49 | var i = 0; 50 | while (i < r) { 51 | var j = i + 1; 52 | perm1[i] = perm1[j]; 53 | i = j; 54 | } 55 | perm1[r] = perm0; 56 | 57 | count[r] = count[r] - 1; 58 | if (count[r] > 0) break; 59 | r++; 60 | } 61 | } 62 | } 63 | 64 | var n = 8; 65 | var ret = fannkuch(n); 66 | 67 | var expected = 22; 68 | if (ret != expected) 69 | print( "ERROR: bad result: expected ", expected, " but got ", ret); 70 | else 71 | print("OK"); 72 | -------------------------------------------------------------------------------- /js_eval.h: -------------------------------------------------------------------------------- 1 | value_t eval_endlist(Node *a, environment_t *env); 2 | value_t eval_math(Node *a, environment_t *env); 3 | value_t eval_neg(Node *a, environment_t *env); // - expr 4 | value_t eval_fcncall(Node *a, environment_t *env); // func( exprlist ) 5 | value_t eval_fcnexpr(Node *a, environment_t *env); // func( exprlist ) 6 | value_t eval_builtin(Node *a, environment_t *env); // builtinfunc( exprlist ) 7 | value_t eval_opassign(Node *a, environment_t *env); // lval (+|-)= rval 8 | value_t eval_assign(Node *a, environment_t *env); // lval = rval 9 | value_t eval_fcnexpr(Node *a, environment_t *env); // fcn ( paramlist ) 10 | value_t eval_fcndef(Node *a, environment_t *env); // function f(.) { .. } 11 | 12 | value_t eval_block (Node *a, environment_t *env); 13 | value_t eval_arg(uint32_t *args, environment_t *env); 14 | value_t eval_num (Node *a, environment_t *env); 15 | value_t eval_badop (Node *a, environment_t *env); 16 | value_t eval_noop (Node *a, environment_t *env); 17 | value_t eval_access (Node *a, environment_t *env); 18 | value_t eval_lookup (Node *a, environment_t *env); 19 | value_t eval_array (Node *n, environment_t *env); 20 | value_t eval_obj (Node *n, environment_t *env); 21 | value_t eval_list(Node *n, environment_t *env); 22 | value_t eval_var(Node *a, environment_t *env); 23 | value_t eval_string(Node *a, environment_t *env); 24 | value_t eval_while(Node *a, environment_t *env); 25 | value_t eval_dowhile(Node *a, environment_t *env); 26 | value_t eval_ifthen(Node *a, environment_t *env); 27 | value_t eval_return(Node *a, environment_t *env); 28 | value_t eval_typeof(Node *a, environment_t *env); 29 | value_t eval_enum(Node *a, environment_t *env); 30 | value_t eval_incr(Node *a, environment_t *env); 31 | value_t eval_tern(Node *a, environment_t *env); 32 | value_t eval_forin(Node *a, environment_t *env); 33 | value_t eval_for(Node *a, environment_t *env); 34 | value_t eval_lor(Node *a, environment_t *env); 35 | value_t eval_land(Node *a, environment_t *env); 36 | value_t eval_pipe(Node *a, environment_t *env); 37 | -------------------------------------------------------------------------------- /tests.bash: -------------------------------------------------------------------------------- 1 | mkdir dbdata 2 | ./jsdb system*.js jsscripts/test_aes3.js 3 | ./jsdb system*.js jsscripts/test_args.js 4 | ./jsdb system*.js jsscripts/test_array.js 5 | ./jsdb system*.js jsscripts/test_assign.js 6 | ./jsdb system*.js jsscripts/test_bin.js 7 | ./jsdb system*.js jsscripts/test_comment.js 8 | ./jsdb system*.js jsscripts/test_comp.js 9 | ./jsdb system*.js jsscripts/test_concat.js 10 | ./jsdb system*.js jsscripts/test_conv.js 11 | ./jsdb system*.js jsscripts/test_cube.js 12 | ./jsdb system*.js jsscripts/test_date.js 13 | ./jsdb system*.js jsscripts/test_dbartree.js 14 | ./jsdb system*.js jsscripts/test_dbbtree.js 15 | ./jsdb system*.js jsscripts/test_dbdocs.js 16 | ./jsdb system*.js jsscripts/test_dbidx.js 17 | ./jsdb system*.js jsscripts/test_db.js 18 | ./jsdb system*.js jsscripts/test_dbtxn.js 19 | ./jsdb system*.js jsscripts/test_dbupdate.js 20 | ./jsdb system*.js jsscripts/test_enum.js 21 | ./jsdb system*.js jsscripts/test_es6scope.js 22 | ./jsdb system*.js jsscripts/test_fcn2.js 23 | ./jsdb system*.js jsscripts/test_fcn.js 24 | ./jsdb system*.js jsscripts/test_for.js 25 | ./jsdb system*.js jsscripts/test_ftw.js 26 | ./jsdb system*.js jsscripts/test_ifthenelse.js 27 | ./jsdb system*.js jsscripts/test_int.js 28 | ./jsdb system*.js jsscripts/test_json.js 29 | ./jsdb system*.js jsscripts/test_math.js 30 | ./jsdb system*.js jsscripts/test_name.js 31 | ./jsdb system*.js jsscripts/test_num32.js 32 | ./jsdb system*.js jsscripts/test_num64.js 33 | ./jsdb system*.js jsscripts/test_num.js 34 | ./jsdb system*.js jsscripts/test_obj.js 35 | ./jsdb system*.js jsscripts/test_parse.js 36 | ./jsdb system*.js jsscripts/test_props.js 37 | ./jsdb system*.js jsscripts/test_proto.js 38 | ./jsdb system*.js jsscripts/test_ray.js 39 | ./jsdb system*.js jsscripts/test_rel.js 40 | ./jsdb system*.js jsscripts/test_semi.js 41 | ./jsdb system*.js jsscripts/test_sort.js 42 | ./jsdb system*.js jsscripts/test_str1.js 43 | ./jsdb system*.js jsscripts/test_str.js 44 | ./jsdb system*.js jsscripts/test_tern.js 45 | ./jsdb system*.js jsscripts/test_this.js 46 | ./jsdb system*.js jsscripts/test_toks.js 47 | ./jsdb system*.js jsscripts/test_var.js 48 | ./jsdb system*.js jsscripts/test_xtn.js 49 | -------------------------------------------------------------------------------- /data/local.mk: -------------------------------------------------------------------------------- 1 | ## Copyright (C) 2002, 2005-2013 Free Software Foundation, Inc. 2 | 3 | ## This program is free software: you can redistribute it and/or modify 4 | ## it under the terms of the GNU General Public License as published by 5 | ## the Free Software Foundation, either version 3 of the License, or 6 | ## (at your option) any later version. 7 | ## 8 | ## This program is distributed in the hope that it will be useful, 9 | ## but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | ## GNU General Public License for more details. 12 | ## 13 | ## You should have received a copy of the GNU General Public License 14 | ## along with this program. If not, see . 15 | 16 | dist_pkgdata_DATA = \ 17 | data/README \ 18 | data/bison.m4 \ 19 | data/c++-skel.m4 \ 20 | data/c++.m4 \ 21 | data/c-like.m4 \ 22 | data/c-skel.m4 \ 23 | data/c.m4 \ 24 | data/glr.c \ 25 | data/glr.cc \ 26 | data/java-skel.m4 \ 27 | data/java.m4 \ 28 | data/lalr1.cc \ 29 | data/lalr1.java \ 30 | data/location.cc \ 31 | data/stack.hh \ 32 | data/variant.hh \ 33 | data/yacc.c 34 | 35 | m4sugardir = $(pkgdatadir)/m4sugar 36 | dist_m4sugar_DATA = \ 37 | data/m4sugar/foreach.m4 \ 38 | data/m4sugar/m4sugar.m4 39 | 40 | xsltdir = $(pkgdatadir)/xslt 41 | dist_xslt_DATA = \ 42 | data/xslt/bison.xsl \ 43 | data/xslt/xml2dot.xsl \ 44 | data/xslt/xml2text.xsl \ 45 | data/xslt/xml2xhtml.xsl 46 | -------------------------------------------------------------------------------- /mongo/jsDbColl.js: -------------------------------------------------------------------------------- 1 | // Database collection implementation 2 | 3 | var DbCollection = function(database, name, options) { 4 | this._database = database; 5 | this._options = options; 6 | var created; 7 | 8 | this._docStore = {}; 9 | this._docStore._hndl = jsdb_createDocStore(database, name, options.size, options.onDisk, &created); 10 | 11 | if (!options.onDisk) 12 | Db.inMem.push(name); 13 | 14 | if (created) 15 | if (!this._docStore._id_ && options.autoIndexId) 16 | this._docStore._id_ = jsdb_createIndex(this._docStore._hndl, {_id:1}, "_id_", "art", 0, true, false); 17 | 18 | Db.catalog[name] = this._docStore; 19 | }; 20 | 21 | Db.prototype.getCollection = function(name) { 22 | this[name] = new DbCollection(this._db, name, {size : Db._defaultSize, onDisk : Db._onDisk, autoIndexId : Db._autoIndexId}); 23 | }; 24 | 25 | Db.prototype.createCollection = function(name, options) { 26 | return this[name] = new DbCollection(this._db, name, options); 27 | }; 28 | 29 | DbCollection.prototype.save = function (document, concern) { 30 | var docId, count, dbtxn = this._dbtxn, result; 31 | 32 | if (!dbtxn) 33 | dbtxn = jsdb_beginTxn(this._database); 34 | 35 | if (jsdb_insertDocs(this._docStore._hndl, document, &docId, &count, dbtxn)) { 36 | result = { nInserted : count}; 37 | if (!this._dbtxn) 38 | jsdb_commitTxn(this._database, dbtxn); 39 | } else { 40 | result = { 41 | nInserted : 0, 42 | writeConcernError : { 43 | code : 64, 44 | errmsg : "timeout" 45 | } 46 | }; 47 | if (!this._dbtxn) 48 | jsdb_rollbackTxn(this._database, dbtxn); 49 | }; 50 | }; 51 | 52 | DbCollection.prototype.createIndex = function(key, options) { 53 | var hndl, prev; 54 | 55 | prev = Object.keys(this._docStore).length - 1; 56 | 57 | if (hndl = jsdb_createIndex(this._docStore._hndl, key, options.name, options.type, options.size, options.unique, options.sparse, options.partialFilterExpression)) 58 | 59 | this._docStore[options.name] = hndl; 60 | else 61 | print ("createIndex error: ", options.name); 62 | 63 | return { 64 | numIndexesBefore : prev, 65 | numIndexesAfter: Object.keys(this._docStore).length - 1, 66 | ok : true 67 | }; 68 | }; 69 | -------------------------------------------------------------------------------- /js_malloc.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #ifndef __APPLE__ 4 | #include 5 | #endif 6 | 7 | #include "js.h" 8 | #include "js_malloc.h" 9 | #include "database/db.h" 10 | #include "database/db_arena.h" 11 | #include "database/db_map.h" 12 | 13 | extern bool mallocDebug; 14 | 15 | // allocate reference counted object 16 | 17 | void *js_alloc(uint32_t size, bool zeroit) { 18 | rawobj_t *mem; 19 | DbAddr addr; 20 | 21 | mem = db_malloc(size + sizeof(rawobj_t), mallocDebug ? false : zeroit); 22 | 23 | if (mallocDebug) { 24 | addr = db_memAddr(mem); 25 | 26 | if (addr.bits && addr.bits != 0xdeadbeef) { 27 | fprintf(stderr, "js_alloc: memory address already in use\n"); 28 | exit(0); 29 | } 30 | } 31 | 32 | mem->weakCnt[0] = 0; 33 | mem->refCnt[0] = 0; 34 | return mem + 1; 35 | } 36 | 37 | // free javascript object 38 | 39 | void js_free(void *obj) { 40 | rawobj_t *mem = obj; 41 | 42 | db_free(mem - 1); 43 | } 44 | 45 | uint32_t js_size (void *obj) { 46 | rawobj_t *raw = obj; 47 | 48 | return db_memSize(raw - 1) - sizeof(rawobj_t); 49 | } 50 | 51 | void *js_realloc(void *old, uint32_t *size, bool zeroit) { 52 | rawobj_t *raw = old, *mem; 53 | uint32_t oldSize; 54 | DbAddr addr; 55 | 56 | addr = db_memAddr(raw - 1); 57 | 58 | // is the new size within the same power of two? 59 | 60 | if (mallocDebug) 61 | if (addr.bits == 0xdeadbeef) 62 | fprintf (stderr, "js_realloc: memory already free!\n"); 63 | 64 | // calc user's size 65 | 66 | oldSize = db_rawSize(addr) - sizeof(rawobj_t); 67 | 68 | // see if it is still witin the allocation 69 | 70 | if (oldSize >= *size) { 71 | *size = oldSize; 72 | return old; 73 | } 74 | 75 | if ((mem = js_alloc(*size, zeroit))) 76 | *size = db_memSize(mem) - sizeof(rawobj_t); 77 | else { 78 | fprintf (stderr, "js_realloc: out of memory!\n"); 79 | exit(1); 80 | } 81 | 82 | // copy contents and release old allocation 83 | 84 | memcpy(mem, raw, oldSize); 85 | 86 | if (zeroit) 87 | memset((char *)mem + oldSize, 0, *size - oldSize); 88 | 89 | // copy reference counts 90 | 91 | *mem[-1].weakCnt = *raw[-1].weakCnt; 92 | *mem[-1].refCnt = *raw[-1].refCnt; 93 | 94 | db_memFree (addr); 95 | return mem; 96 | } 97 | 98 | -------------------------------------------------------------------------------- /mongo/jsDbFind.js: -------------------------------------------------------------------------------- 1 | var DbCursor = function (collection, query, projection, reverse) { 2 | this._collection = collection; 3 | this._projection = projection; 4 | this._reverse = reverse; 5 | this._query = query; 6 | }; 7 | 8 | DbCollection.prototype.find = function (query, projection) { 9 | var cursor = new DbCursor(this, query, projection, false); 10 | return cursor; 11 | }; 12 | 13 | DbCursor.prototype.sort = function (index, start, limit) { 14 | this._index = index; 15 | this._start = start; 16 | this._limit = limit; 17 | return this; 18 | }; 19 | 20 | DbCursor.prototype.hasNext = function () { 21 | var document; 22 | 23 | if (!this._collection._docStore._hndl) 24 | this._collection._docStore = this._collection._install(); 25 | 26 | if (!this._cursor) 27 | if (this._index) 28 | this._cursor = jsdb_createCursor(this._collection._docStore[this._index], this._reverse, this._start, this._limit); 29 | else 30 | this._cursor = jsdb_createIterator(this._collection._docStore._hndl); 31 | 32 | if (this._doc) 33 | return true; 34 | 35 | if (this._index) { 36 | while (this._nextDoc = jsdb_nextKey(this._cursor)) 37 | if (jsdb_findDocs(this._query, this._nextDoc)) 38 | return true; 39 | } else { 40 | while (this._nextDoc = jsdb_nextDoc(this._cursor)) 41 | if (jsdb_findDocs(this._query, this._nextDoc)) 42 | return true; 43 | } 44 | 45 | return false; 46 | }; 47 | 48 | DbCursor.prototype.next = function () { 49 | var document; 50 | 51 | if (!this._collection._docStore) 52 | this._collection._docStore = this._collection._install(); 53 | 54 | if (!this._cursor) 55 | if (this._index) 56 | this._cursor = jsdb_createCursor(this._collection._docStore[this._index], this._reverse, this._start, this._limit); 57 | else 58 | this._cursor = jsdb_createIterator(this._collection._docStore._hndl); 59 | 60 | if (document = this._nextDoc) 61 | return this._nextDoc = null, document; 62 | 63 | if (this._index) { 64 | while (this._nextDoc = jsdb_nextKey(this._cursor)) 65 | if (jsdb_findDocs(this._query, this._nextDoc)) 66 | return this._nextDoc; 67 | } else { 68 | while (this._nextDoc = jsdb_nextDoc(this._cursor)) 69 | if (jsdb_findDocs(this._query, document)) 70 | return this._nextDoc; 71 | } 72 | 73 | return null; 74 | }; 75 | -------------------------------------------------------------------------------- /speed1.js: -------------------------------------------------------------------------------- 1 | var count = 0; 2 | var idx; 3 | 4 | var txn; 5 | var start = new Date(); 6 | 7 | var db, dbname; 8 | 9 | for (dbname in catalog.db) 10 | db = new Db(dbname), db.drop(); 11 | 12 | db = new Db("tstdb", {onDisk:true}); 13 | var store = db.createDocStore("collection", {onDisk:true}); 14 | 15 | while(count<1000) { 16 | var id, cnt; 17 | idx = 0; 18 | 19 | // txn = jsdb_beginTxn(); 20 | var array = []; 21 | 22 | while(idx<1000) { 23 | array[idx] = { 24 | doc : count * 1000 + idx, 25 | cnt : count, 26 | idx : idx, 27 | /* text0 : "This is a test string designed to make this record bigger0", 28 | text1 : "This is a test string designed to make this record bigger1", 29 | text2 : "This is a test string designed to make this record bigger2", 30 | text3 : "This is a test string designed to make this record bigger3", 31 | text4 : "This is a test string designed to make this record bigger4", 32 | text5 : "This is a test string designed to make this record bigger5", 33 | text6 : "This is a test string designed to make this record bigger6", 34 | text7 : "This is a test string designed to make this record bigger7", 35 | text8 : "This is a test string designed to make this record bigger8", 36 | text9 : "This is a test string designed to make this record bigger9" 37 | */ }; 38 | idx += 1; 39 | } 40 | 41 | // print ("batch: ", count, " item: ", idx); 42 | store.writeDocs(array); 43 | // jsdb_commitTxn(); 44 | count += 1; 45 | // print ("batch: ", count); 46 | } 47 | 48 | var stop = new Date(); 49 | var ins = (stop - start) / 1000.; 50 | 51 | start = stop; 52 | 53 | var iterator, doc; 54 | 55 | iterator = store.createIterator(); 56 | iterator.seek(IteratorOp.opBegin); 57 | 58 | var reccnt = 0, docId; 59 | 60 | while(docId = iterator.next()) { 61 | doc = docId.retrieve(); 62 | if (!(reccnt % 998)) { 63 | print("idx: ", reccnt, " docId: ", doc.docId, " doc.doc: ", doc.doc); 64 | } 65 | reccnt += 1; 66 | } 67 | 68 | var stop = new Date(); 69 | 70 | print ("found: ", reccnt, " should be 1000000"); 71 | print ("insert: ", ins, " seconds"); 72 | print ("scan verify: ", (stop - start) / 1000., " seconds"); 73 | -------------------------------------------------------------------------------- /data/README: -------------------------------------------------------------------------------- 1 | -*- outline -*- 2 | 3 | This directory contains data needed by Bison. 4 | 5 | * Skeletons 6 | Bison skeletons: the general shapes of the different parser kinds, 7 | that are specialized for specific grammars by the bison program. 8 | 9 | Currently, the supported skeletons are: 10 | 11 | - yacc.c 12 | It used to be named bison.simple: it corresponds to C Yacc 13 | compatible LALR(1) parsers. 14 | 15 | - lalr1.cc 16 | Produces a C++ parser class. 17 | 18 | - lalr1.java 19 | Produces a Java parser class. 20 | 21 | - glr.c 22 | A Generalized LR C parser based on Bison's LALR(1) tables. 23 | 24 | - glr.cc 25 | A Generalized LR C++ parser. Actually a C++ wrapper around glr.c. 26 | 27 | These skeletons are the only ones supported by the Bison team. 28 | Because the interface between skeletons and the bison program is not 29 | finished, *we are not bound to it*. In particular, Bison is not 30 | mature enough for us to consider that "foreign skeletons" are 31 | supported. 32 | 33 | * m4sugar 34 | This directory contains M4sugar, sort of an extended library for M4, 35 | which is used by Bison to instantiate the skeletons. 36 | 37 | * xslt 38 | This directory contains XSLT programs that transform Bison's XML output 39 | into various formats. 40 | 41 | - bison.xsl 42 | A library of routines used by the other XSLT programs. 43 | 44 | - xml2dot.xsl 45 | Conversion into GraphViz's dot format. 46 | 47 | - xml2text.xsl 48 | Conversion into text. 49 | 50 | - xml2xhtml.xsl 51 | Conversion into XHTML. 52 | 53 | ----- 54 | 55 | Copyright (C) 2002, 2008-2013 Free Software Foundation, Inc. 56 | 57 | This file is part of GNU Bison. 58 | 59 | This program is free software: you can redistribute it and/or modify 60 | it under the terms of the GNU General Public License as published by 61 | the Free Software Foundation, either version 3 of the License, or 62 | (at your option) any later version. 63 | 64 | This program is distributed in the hope that it will be useful, 65 | but WITHOUT ANY WARRANTY; without even the implied warranty of 66 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 67 | GNU General Public License for more details. 68 | 69 | You should have received a copy of the GNU General Public License 70 | along with this program. If not, see . 71 | -------------------------------------------------------------------------------- /oldjsdb/jsdb_dbdocs.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | typedef struct { 4 | uint64_t refCnt[1]; // handle reference count (must be first) 5 | uint64_t timestamp; // iterator timestamp 6 | value_t docStore; // DocStore handle 7 | DbAddr pqAddr; // iterator snapshop 8 | DocId docId; // current DocID 9 | DocId txnId; // owning txn 10 | } Iterator; 11 | 12 | // document stored in a docStore 13 | // document body follows 14 | 15 | #define IndexMapCnt 8 16 | 17 | typedef struct { 18 | struct { 19 | uint64_t docVer; // key inserted at doc version 20 | uint32_t id; // index ID 21 | uint32_t cnt; // count of map entries 22 | DbAddr next; // next map segment 23 | } entry[IndexMapCnt]; 24 | } IndexMap; 25 | 26 | typedef struct { 27 | uint64_t docVer; // document version sequence or zero if not in use 28 | uint64_t docTs; // copy of commit timestamp 29 | DbAddr oldDoc[1]; // next older document version 30 | DbAddr indexMap; // Key IndexID to DocVer map 31 | DocId txnId; // document txn (zeroed after expiration) 32 | DocId docId; // document Id 33 | uint32_t docSize; // size of document 34 | } DbDoc; 35 | 36 | typedef struct { 37 | uint64_t docSize; // overall size of documents 38 | uint64_t docCount; // overall number of documents 39 | uint64_t idxListVer; // docIdxList version number 40 | DbAddr docIdxList; // list of collection indexes 41 | FreeList docWait[MAX_set][MaxDocType]; // documents waiting reclamation 42 | } DbStore; 43 | 44 | #define docStoreAddr(map)((DbStore *)(map->arena + 1)) 45 | 46 | uint64_t get64(uint8_t *from); 47 | void store64(uint8_t *to, uint64_t what); 48 | uint64_t marshal_doc(DbMap *map, value_t document); 49 | void *allocateDoc(DbMap *map, uint32_t size, DbAddr *addr, uint32_t set); 50 | void *findDoc(value_t docStore, uint64_t docBits); 51 | uint64_t findDocVer(DbMap *docStore, DocId docId, DocId txnId, uint64_t ts); 52 | 53 | Status deleteDoc(DbMap *map, uint64_t docId, uint64_t txnBits); 54 | extern value_t createIterator(value_t docStore, DbMap *map, bool atEnd); 55 | 56 | value_t iteratorSeek(Iterator *it, DbMap *map, uint64_t docBits); 57 | value_t iteratorNext(Iterator *it, DbMap *map); 58 | value_t iteratorPrev(Iterator *it, DbMap *map); 59 | 60 | value_t createDatabase (value_t dbname, bool onDisk); 61 | value_t createDocStore(DbMap *map, value_t name, uint64_t size, bool onDisk, bool *created); 62 | -------------------------------------------------------------------------------- /sunspider/string-fasta.js: -------------------------------------------------------------------------------- 1 | // The Great Computer Language Shootout 2 | // http://shootout.alioth.debian.org 3 | // 4 | // Contributed by Ian Osgood 5 | 6 | var last = 42, A = 3877, C = 29573, M = 139968; 7 | 8 | function rand(max) { 9 | last = (last * A + C) % M; 10 | return max * last / M; 11 | } 12 | 13 | var ALU = 14 | "GGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGG" + 15 | "GAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGA" + 16 | "CCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAAT" + 17 | "ACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCA" + 18 | "GCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGG" + 19 | "AGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCC" + 20 | "AGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAA"; 21 | 22 | var IUB = { 23 | a:0.27, c:0.12, g:0.12, t:0.27, 24 | B:0.02, D:0.02, H:0.02, K:0.02, 25 | M:0.02, N:0.02, R:0.02, S:0.02, 26 | V:0.02, W:0.02, Y:0.02 27 | }; 28 | 29 | var HomoSap = { 30 | a: 0.3029549426680, 31 | c: 0.1979883004921, 32 | g: 0.1975473066391, 33 | t: 0.3015094502008 34 | }; 35 | 36 | function makeCumulative(table) { 37 | var last = null; 38 | for (var c in table) { 39 | if (last) table[c] += table[last]; 40 | last = c; 41 | } 42 | } 43 | 44 | function fastaRepeat(n, seq) { 45 | var seqi = 0, lenOut = 60; 46 | while (n>0) { 47 | if (n0) { 64 | if (n 3 | #include 4 | #include "httpd.h" 5 | #include "http_core.h" 6 | #include "http_protocol.h" 7 | #include "http_request.h" 8 | 9 | /* Define prototypes of our functions in this module */ 10 | static void register_hooks(apr_pool_t *pool); 11 | static int jsdb_handler(request_rec *r); 12 | 13 | /* Define our module as an entity and assign a function for registering hooks */ 14 | 15 | module AP_MODULE_DECLARE_DATA jsdb_module = 16 | { 17 | STANDARD20_MODULE_STUFF, 18 | NULL, // Per-directory configuration handler 19 | NULL, // Merge handler for per-directory configurations 20 | NULL, // Per-server configuration handler 21 | NULL, // Merge handler for per-server configurations 22 | NULL, // Any directives we may have for httpd 23 | register_hooks // Our hook registering function 24 | }; 25 | 26 | 27 | /* register_hooks: Adds a hook to the httpd process */ 28 | static void register_hooks(apr_pool_t *pool) 29 | { 30 | /* Hook the request handler */ 31 | ap_hook_handler(jsdb_handler, NULL, NULL, APR_HOOK_LAST); 32 | } 33 | 34 | /* The handler function for our module. 35 | * This is where all the fun happens! 36 | */ 37 | 38 | static int jsdb_handler(request_rec *r) 39 | { 40 | /* First off, we need to check if this is a call for the "jsdb" handler. 41 | * If it is, we accept it and do our things, it not, we simply return DECLINED, 42 | * and Apache will try somewhere else. 43 | */ 44 | if (!r->handler /*|| strcmp(r->handler, "jsdb")*/) return (DECLINED); 45 | 46 | // The first thing we will do is write a simple "Hello, world!" back to the client. 47 | ap_rputs("Helloooooooooo wooooooooorld!\n", r); 48 | if (r->handler) ap_rputs("handler = ",r), ap_rputs(r->handler,r), ap_rputs("\n",r); 49 | if (r->method) ap_rputs("method = ",r), ap_rputs(r->method,r), ap_rputs("\n",r); 50 | if (r->filename) ap_rputs("filename = ",r), ap_rputs(r->filename,r), ap_rputs("\n",r); 51 | if (r->args) ap_rputs("args = ",r), ap_rputs(r->args,r), ap_rputs("\n",r); 52 | if (r->user) ap_rputs("user = ",r), ap_rputs(r->user,r), ap_rputs("\n",r); 53 | if (r->useragent_ip) ap_rputs("useragent = ",r), ap_rputs(r->useragent_ip,r), ap_rputs("\n",r); 54 | 55 | int pid = getpid(); 56 | char pidStr[64]; 57 | sprintf(pidStr, "%d", pid); 58 | ap_rputs("pid = ",r), ap_rputs(pidStr,r), ap_rputs("\n",r); 59 | return OK; 60 | } 61 | -------------------------------------------------------------------------------- /oldjsdb/jsdb_dbbtree.c: -------------------------------------------------------------------------------- 1 | #include "jsdb.h" 2 | #include "jsdb_db.h" 3 | 4 | #define pagebits 13 // btree interior page size 5 | #define leafxtra 0 // btree leaf extra bits 6 | 7 | #if (pagebits > Btree_maxbits) 8 | #error btree interior pages too large 9 | #endif 10 | 11 | #if (pagebits + leafxtra > Btree_maxbits) 12 | #error btree leaf pages too large 13 | #endif 14 | 15 | // create an empty page 16 | 17 | uint64_t btreeNewPage (DbMap *index, uint8_t lvl) { 18 | BtreeIndex *btree = btreeIndex(index); 19 | BtreePageType type; 20 | BtreePage *page; 21 | uint32_t size; 22 | DbAddr addr; 23 | 24 | size = btree->pageSize; 25 | 26 | if (lvl) 27 | type = Btree_interior; 28 | else { 29 | type = Btree_leafPage; 30 | size <<= btree->leafXtra; 31 | } 32 | 33 | if ((addr.bits = allocObj(index, &btree->freePages[type], type, size, true))) 34 | page = getObj(index, addr); 35 | else 36 | return 0; 37 | 38 | page->lvl = lvl; 39 | page->min = size; 40 | return addr.bits; 41 | } 42 | 43 | Status btreeInit(DbMap *index) { 44 | BtreeIndex *btree = btreeIndex(index); 45 | BtreePage *page; 46 | BtreeSlot *slot; 47 | uint8_t *buff; 48 | 49 | btree->pageSize = 1 << pagebits; 50 | btree->pageBits = pagebits; 51 | btree->leafXtra = leafxtra; 52 | 53 | // initial btree root & leaf pages 54 | 55 | if ((btree->leaf.bits = btreeNewPage(index, 0))) 56 | page = getObj(index, btree->leaf); 57 | else 58 | return ERROR_outofmemory; 59 | 60 | // set up new leaf page with stopper key 61 | 62 | page->min -= 1; 63 | page->cnt = 1; 64 | page->act = 1; 65 | 66 | buff = keyaddr(page, page->min); 67 | buff[0] = 0; 68 | 69 | // set up stopper slot 70 | 71 | slot = slotptr(page, 1); 72 | slot->type = Btree_stopper; 73 | slot->off = page->min; 74 | 75 | if ((btree->root.bits = btreeNewPage(index, 1))) 76 | page = getObj(index, btree->root); 77 | else 78 | return ERROR_outofmemory; 79 | 80 | // set up new root page with stopper key 81 | 82 | btree->root.type = Btree_rootPage; 83 | page->min -= 2 + sizeof(uint64_t); 84 | page->cnt = 1; 85 | page->act = 1; 86 | 87 | // set up stopper key 88 | 89 | buff = keyaddr(page, page->min); 90 | buff[0] = 1 + sizeof(uint64_t); 91 | buff[1] = 0; 92 | store64(buff + 2, btree->leaf.bits); 93 | 94 | // set up slot 95 | 96 | slot = slotptr(page, 1); 97 | slot->type = Btree_stopper; 98 | slot->off = page->min; 99 | return OK; 100 | } 101 | -------------------------------------------------------------------------------- /sunspider/string-validate-input.js: -------------------------------------------------------------------------------- 1 | eetters = new Array("a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"); 2 | numbers = new Array(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26); 3 | colors = new Array("FF","CC","99","66","33","00"); 4 | 5 | var endResult; 6 | 7 | function doTest() 8 | { 9 | endResult = ""; 10 | 11 | // make up email address 12 | for (var k=0;k<4000;k++) 13 | { 14 | username = makeName(6); 15 | (k%2)?email=username+"@mac.com":email=username+"(at)mac.com"; 16 | 17 | // validate the email address 18 | var pattern = /^[a-zA-Z0-9\-\._]+@[a-zA-Z0-9\-_]+(\.?[a-zA-Z0-9\-_]*)\.[a-zA-Z]{2,3}$/; 19 | 20 | if(pattern.test(email)) 21 | { 22 | var r = email + " appears to be a valid email address."; 23 | addResult(r); 24 | } 25 | else 26 | { 27 | r = email + " does NOT appear to be a valid email address."; 28 | addResult(r); 29 | } 30 | } 31 | 32 | // make up ZIP codes 33 | for (var s=0;s<4000;s++) 34 | { 35 | var zipGood = true; 36 | var zip = makeNumber(4); 37 | (s%2)?zip=zip+"xyz":zip=zip.concat("7"); 38 | 39 | // validate the zip code 40 | for (var i = 0; i < zip.length; i++) { 41 | var ch = zip.charAt(i); 42 | if (ch < "0" || ch > "9") { 43 | zipGood = false; 44 | r = zip + " contains letters."; 45 | addResult(r); 46 | } 47 | } 48 | if (zipGood && zip.length>5) 49 | { 50 | zipGood = false; 51 | r = zip + " is longer than five characters."; 52 | addResult(r); 53 | } 54 | if (zipGood) 55 | { 56 | r = zip + " appears to be a valid ZIP code."; 57 | addResult(r); 58 | } 59 | } 60 | } 61 | 62 | function makeName(n) 63 | { 64 | var tmp = ""; 65 | for (var i=0;imoduleSize; 11 | 12 | if( start > slot ) 13 | return fn; 14 | } 15 | 16 | return (firstNode *)table; 17 | } 18 | 19 | uint32_t newNode (parseData *pd, nodeType type, uint32_t size, bool zero) { 20 | uint32_t blks = (size + sizeof(Node) - 1)/sizeof(Node); 21 | uint32_t addr = pd->tableNext, newSize[1]; 22 | Node *node; 23 | 24 | if( blks + pd->tableNext >= pd->tableSize ) { 25 | if( pd->tableSize ) 26 | pd->tableSize *= 2; 27 | else 28 | pd->tableSize = 4090; 29 | 30 | *newSize = pd->tableSize * sizeof(Node); 31 | 32 | if (pd->table) 33 | pd->table = js_realloc (pd->table, newSize, false); 34 | else 35 | pd->table = js_alloc (*newSize, false); 36 | 37 | pd->tableSize = *newSize / sizeof(Node); 38 | } 39 | 40 | node = pd->table + pd->tableNext; 41 | 42 | if (zero) 43 | memset (node, 0, size); 44 | 45 | node->bits = type; 46 | node->lineNo = pd->lineNo; 47 | 48 | pd->tableNext += blks; 49 | return addr; 50 | } 51 | 52 | char convLit(char quoted) { 53 | switch(quoted) { 54 | case 0x0a: return 0; 55 | case 0x0d: return 0; 56 | case 'f': return 0x0c; 57 | case 'r': return 0x0d; 58 | case 'n': return 0x0a; 59 | case 't': return 0x09; 60 | case 'b': return 0x08; 61 | } 62 | 63 | return quoted; 64 | } 65 | 66 | uint32_t newStrNode (parseData *pd, char *text, uint32_t size) { 67 | uint32_t len = 0, addr, off = 0, max, idx; 68 | stringNode *sn; 69 | char c; 70 | 71 | for(max = 1; max < size; max++) 72 | switch(text[max]) { 73 | case '\\': continue; 74 | case 0x0a: pd->lineNo++; continue; 75 | case 0x0d: continue; 76 | default: len++; continue; 77 | } 78 | 79 | max--; // discard trailing quote mark 80 | len--; // discard trailing quote mark 81 | 82 | addr = newNode(pd, node_string, sizeof(stringNode) + len + 1, false); 83 | sn = (stringNode *)(pd->table + addr); 84 | sn->str.len = len; 85 | 86 | for(idx = 1; idx < max && off < len; idx++) 87 | switch((c = text[idx])) { 88 | case '\\': 89 | if ((sn->str.val[off] = convLit(text[++idx]))) 90 | off++; 91 | continue; 92 | 93 | case 0x0a: continue; 94 | case 0x0d: continue; 95 | default: sn->str.val[off++] = c; 96 | } 97 | 98 | return addr; 99 | } 100 | -------------------------------------------------------------------------------- /js_vector.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #ifndef __APPLE__ 4 | #include 5 | #endif 6 | 7 | #include "js.h" 8 | #include "js_malloc.h" 9 | #include "database/db_malloc.h" 10 | 11 | extern bool mallocDebug; 12 | 13 | #define firstCapacity 10 14 | 15 | // duplicate the vector 16 | 17 | void *vec_dup(void *vector) { 18 | rawobj_t *raw = vector, *mem; 19 | uint32_t size; 20 | 21 | if (!vector) 22 | return NULL; 23 | 24 | size = js_size(vec_raw(vector)); 25 | 26 | if ((mem = js_alloc(size, false))) 27 | memcpy(mem, raw, size); 28 | else { 29 | fprintf (stderr, "vec_dup: out of memory!\n"); 30 | exit(1); 31 | } 32 | 33 | *mem[-1].refCnt = *raw[-1].refCnt; 34 | *mem[-1].weakCnt = *raw[-1].weakCnt; 35 | return (uint32_t *)mem + 2; 36 | } 37 | 38 | // dynamically grow the vector 39 | 40 | void *vec_grow(void *vector, uint32_t increment, uint32_t itemsize, bool map) { 41 | uint32_t dbl_cur = 2*vec_max(vector); 42 | uint32_t min_needed = vec_cnt(vector) + increment; 43 | uint32_t cap = dbl_cur > min_needed ? dbl_cur : min_needed; 44 | uint32_t off, size, mapSize = 0, *p; 45 | //rawobj_t *raw, *nxt; 46 | 47 | // raw = (rawobj_t *)v; 48 | 49 | if (cap < firstCapacity) 50 | cap = firstCapacity; 51 | 52 | if (map) { 53 | if (cap < 255) { 54 | mapSize = sizeof(uint8_t); 55 | } else if (cap < 65535) { 56 | mapSize = sizeof(uint16_t); 57 | } else { 58 | mapSize = sizeof(uint32_t); 59 | } 60 | } 61 | 62 | size = itemsize * cap; 63 | size += sizeof(int) * 2; 64 | size += mapSize * 3 * cap / 2; 65 | 66 | p = js_alloc(size, false); 67 | // nxt = (rawobj_t *)p; 68 | 69 | if (vector) { 70 | off = vec_cnt(vector) * itemsize + 2 * sizeof(int); 71 | memcpy (p, vec_raw(vector), off); 72 | memset ((uint8_t *)p + off, 0, size - off); 73 | js_free(vec_raw(vector)); 74 | } else 75 | memset (p, 0, size); 76 | 77 | p[0] = cap; 78 | return p+2; 79 | } 80 | 81 | // slice slots from beginning of the vector 82 | 83 | void *vec_sliceqty(void *vector, uint32_t qty, uint32_t itemsize) { 84 | uint8_t *dest; 85 | uint32_t idx; 86 | 87 | if (!vector) 88 | return NULL; 89 | 90 | if (vec_size(vector) < qty) { 91 | vec_size(vector) = 0; 92 | return vector; 93 | } 94 | 95 | vec_size(vector) -= qty; 96 | dest = vector; 97 | 98 | for (idx = 0; idx < vec_size(vector); idx++) { 99 | memcpy (dest, dest + qty * itemsize, itemsize); 100 | dest += itemsize; 101 | } 102 | 103 | return vector; 104 | } 105 | -------------------------------------------------------------------------------- /data/c-like.m4: -------------------------------------------------------------------------------- 1 | -*- Autoconf -*- 2 | 3 | # Common code for C-like languages (C, C++, Java, etc.) 4 | 5 | # Copyright (C) 2012-2013 Free Software Foundation, Inc. 6 | 7 | # This program is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # This program is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with this program. If not, see . 19 | 20 | # b4_comment_(TEXT, OPEN, CONTINUE, END) 21 | # -------------------------------------- 22 | # Put TEXT in comment. Avoid trailing spaces: don't indent empty lines. 23 | # Avoid adding indentation to the first line, as the indentation comes 24 | # from OPEN. That's why we don't patsubst([$1], [^\(.\)], [ \1]). 25 | # 26 | # Prefix all the output lines with PREFIX. 27 | m4_define([b4_comment_], 28 | [$2[]m4_bpatsubst(m4_expand([[$1]]), [ 29 | \(.\)], [ 30 | $3\1])$4]) 31 | 32 | 33 | # b4_comment(TEXT, [PREFIX]) 34 | # -------------------------- 35 | # Put TEXT in comment. Prefix all the output lines with PREFIX. 36 | m4_define([b4_comment], 37 | [b4_comment_([$1], [$2/* ], [$2 ], [ */])]) 38 | 39 | 40 | 41 | 42 | # b4_dollar_dollar_(VALUE, FIELD, DEFAULT-FIELD) 43 | # ---------------------------------------------- 44 | # If FIELD (or DEFAULT-FIELD) is non-null, return "VALUE.FIELD", 45 | # otherwise just VALUE. Be sure to pass "(VALUE)" is VALUE is a 46 | # pointer. 47 | m4_define([b4_dollar_dollar_], 48 | [b4_symbol_value([$1], 49 | m4_if([$2], [[]], 50 | [[$3]], [[$2]]))]) 51 | 52 | # b4_dollar_pushdef(VALUE-POINTER, DEFAULT-FIELD, LOCATION) 53 | # b4_dollar_popdef 54 | # --------------------------------------------------------- 55 | # Define b4_dollar_dollar for VALUE and DEFAULT-FIELD, 56 | # and b4_at_dollar for LOCATION. 57 | m4_define([b4_dollar_pushdef], 58 | [m4_pushdef([b4_dollar_dollar], 59 | [b4_dollar_dollar_([$1], m4_dquote($][1), [$2])])dnl 60 | m4_pushdef([b4_at_dollar], [$3])dnl 61 | ]) 62 | m4_define([b4_dollar_popdef], 63 | [m4_popdef([b4_at_dollar])dnl 64 | m4_popdef([b4_dollar_dollar])dnl 65 | ]) 66 | -------------------------------------------------------------------------------- /speed2.js: -------------------------------------------------------------------------------- 1 | var count = 0; 2 | var idx; 3 | 4 | var txn, docId; 5 | var start = new Date(); 6 | 7 | var db, dbname; 8 | 9 | for (dbname in catalog.db) 10 | db = new Db(dbname), db.drop(); 11 | 12 | db = new Db("tstdb", {onDisk:true}); 13 | 14 | var store = db.createDocStore("collection", {onDisk:true}); 15 | var index = store.createIndex("speedIdx", {onDisk:true, idxType:0}, {doc:"fwd:dbl"}); 16 | 17 | while(count<1000) { 18 | var id, cnt; 19 | idx = 0; 20 | var docIds = []; 21 | 22 | // txn = jsdb_beginTxn(); 23 | var array = [], key = []; 24 | 25 | while(idx<1000) { 26 | // print ("batch: ", count, " item: ", idx); 27 | array[idx] = { 28 | doc : Math.random() * (count * 1000 + idx), 29 | cnt : count, 30 | idx : idx, 31 | /* text0 : "This is a test string designed to make this record bigger0", 32 | text1 : "This is a test string designed to make this record bigger1", 33 | text2 : "This is a test string designed to make this record bigger2", 34 | text3 : "This is a test string designed to make this record bigger3", 35 | text4 : "This is a test string designed to make this record bigger4", 36 | text5 : "This is a test string designed to make this record bigger5", 37 | text6 : "This is a test string designed to make this record bigger6", 38 | text7 : "This is a test string designed to make this record bigger7", 39 | text8 : "This is a test string designed to make this record bigger8", 40 | text9 : "This is a test string designed to make this record bigger9" 41 | */ }; 42 | idx += 1; 43 | } 44 | 45 | docIds = store.writeDocs(array); 46 | 47 | for( idx = 0; idx<1000;idx++) 48 | index.insertKey(docIds[idx], array[idx].doc); 49 | 50 | // jsdb_commitTxn(); 51 | count += 1; 52 | // print ("batch: ", count); 53 | } 54 | 55 | var stop = new Date(); 56 | var ins = (stop - start) / 1000.; 57 | start = stop; 58 | 59 | var cursor, doc; 60 | 61 | cursor = index.createCursor(); 62 | 63 | var reccnt = 0; 64 | var prev = 0; 65 | 66 | while( doc = cursor.move(CursorOp.opNext)) { 67 | key = cursor.keyAt(); 68 | 69 | if (!(reccnt % 2500)) { 70 | print(reccnt, " docId: ", cursor.docIdAt(), "\tkey: [", key, "]"); 71 | } 72 | 73 | if ( key < prev) 74 | print ("out of order record #", reccnt, "\tkey: ", doc.doc, " prev: ", prev); 75 | 76 | prev = key; 77 | reccnt += 1; 78 | } 79 | 80 | var stop = new Date(); 81 | 82 | print ("insert: ", ins, " seconds"); 83 | print ("found: ", reccnt, " should be 1000000"); 84 | print ("sort verify: ", (stop - start) / 1000., " seconds"); 85 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text eol=lf 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /oldjsdb/jsdb_dbartindex.c: -------------------------------------------------------------------------------- 1 | #include "jsdb.h" 2 | #include "jsdb_db.h" 3 | 4 | bool artindex_hasdup (DbMap *index, DbAddr *base, KeySuffix *suffix) { 5 | 6 | return false; 7 | } 8 | 9 | Status artIndexKey (DbMap *index, DbDoc *doc, DocId docId, uint32_t set) { 10 | DbAddr *base, *tail, newNode; 11 | uint32_t off = 0, size = 0; 12 | ARTEnd *endNode, *sfxNode; 13 | uint8_t buff[MAX_key]; 14 | KeySuffix suffix[1]; 15 | uint8_t *keys; 16 | IndexKey *key; 17 | value_t field; 18 | int len; 19 | 20 | keys = getObj(index, indexAddr(index)->keys); 21 | base = artIndexAddr(index)->root; 22 | key = (IndexKey *)keys; 23 | 24 | // add each key field to the ARTree 25 | 26 | while (key->type != key_end) { 27 | value_t name; 28 | 29 | name.bits = vt_string; 30 | name.str = key->name; 31 | name.aux = key->len; 32 | 33 | field = lookupDoc((document_t *)(doc + 1), name); 34 | 35 | len = keyFld(field, key, buff, MAX_key - size); 36 | 37 | if (len < 0) 38 | return ERROR_keytoolong; 39 | 40 | base = artAppendKeyFld(index, base, set, buff, len); 41 | size += len; 42 | 43 | off += sizeof(IndexKey) + key->len; 44 | key = (IndexKey *)(keys + off); 45 | 46 | // are we continuing with the next field 47 | // in a current index key? 48 | 49 | if (base->type == FldEnd) { 50 | endNode = getObj(index, *base); 51 | base = endNode->next; 52 | continue; 53 | } 54 | 55 | // splice a FldEnd node into the tree 56 | 57 | newNode.bits = artAllocateNode(index, set, FldEnd, sizeof(ARTEnd)); 58 | endNode = getObj(index, newNode); 59 | endNode->pass->bits = base->bits; 60 | endNode->pass->mutex = 0; 61 | base->bits = newNode.bits; 62 | base = endNode->next; 63 | } 64 | 65 | store64(suffix->docId, docId.bits); 66 | 67 | // enforce unique constraint 68 | 69 | if (indexAddr(index)->opts & index_unique) 70 | if (base->type == Suffix) 71 | if (artindex_hasdup (index, base, suffix)) { 72 | unlockLatch(base->latch); 73 | return ERROR_duplicatekey; 74 | } 75 | 76 | // splice a suffix node into the tree 77 | // after the last key field. 78 | 79 | if (base->type == Suffix) { 80 | sfxNode = getObj(index, *base); 81 | unlockLatch(base->latch); 82 | } else { 83 | newNode.bits = artAllocateNode(index, set, Suffix, sizeof(ARTEnd)); 84 | sfxNode = getObj(index, newNode); 85 | sfxNode->next->bits = base->bits; 86 | sfxNode->next->mutex = 0; 87 | base->bits = newNode.bits; 88 | } 89 | 90 | // append the suffix string to the end of the key 91 | 92 | tail = artAppendKeyFld(index, sfxNode->next, set, suffix->bytes, sizeof(KeySuffix)); 93 | 94 | // and mark the end of the key 95 | 96 | tail->type = KeyEnd; 97 | unlockLatch(tail->latch); 98 | return OK; 99 | } 100 | -------------------------------------------------------------------------------- /oldjsdb/jsdb_dbtxn.c: -------------------------------------------------------------------------------- 1 | #include "jsdb.h" 2 | #include "jsdb_db.h" 3 | 4 | // Unexpired database transactions are documents in the database arena. 5 | // The individual step structure addresses are pushed onto a Frame, 6 | // where each step DbAddr stores the step collection name and documentId. 7 | 8 | // begin a transaction 9 | 10 | uint64_t txnBegin (DbMap *db) { 11 | uint32_t set = getSet(db); 12 | DocId txnId; 13 | Txn *txn; 14 | 15 | txnId.bits = allocDocId(db, &database(db)->freeTxn[set][Txn_id], NULL); 16 | txn = fetchIdSlot(db, txnId); 17 | txn->set = set; 18 | 19 | return txnId.bits; 20 | } 21 | 22 | // add a step to a transaction 23 | 24 | Status txnStep (DbMap *docStore, DocId txnId, DocId docId, TxnStepType type) { 25 | RedBlack *entry = docStore->entry; 26 | DbMap *db = docStore->parent; 27 | Txn *txn = fetchIdSlot(db, txnId); 28 | uint32_t set = txn->set; 29 | TxnStep *txnStep; 30 | ChildMap *child; 31 | DbAddr step; 32 | 33 | child = (ChildMap *)(entry->key + entry->keyLen); 34 | if ((step.bits = allocObj(db, &database(db)->freeTxn[set][Txn_step], type, sizeof(TxnStep), false))) 35 | txnStep = getObj(db, step); 36 | else 37 | return ERROR_outofmemory; 38 | 39 | txnStep->hndlId = child->id; 40 | txnStep->docId.bits = docId.bits; 41 | 42 | if (addSlotToFrame(db, txn->txnFrame, step.bits)) 43 | return OK; 44 | 45 | return ERROR_outofmemory; 46 | } 47 | 48 | // TODO -- implement commit/rollback 49 | 50 | Status txnRollback(DbMap *db, uint64_t txnBits) { 51 | uint64_t addr; 52 | DocId txnId; 53 | DbAddr slot; 54 | Txn *txn; 55 | 56 | txnId.bits = txnBits; 57 | txn = fetchIdSlot(db, txnId); 58 | addr = txn->txnFrame->bits; 59 | 60 | while (addr) { 61 | Frame *frame = getObj(db, *txn->txnFrame); 62 | while (txn->txnFrame->nslot) 63 | addSlotToFrame(db, &database(db)->freeTxn[txn->set][Txn_step], frame->slots[--txn->txnFrame->nslot].bits); 64 | 65 | addr = frame->next.bits; 66 | returnFreeFrame(db, *txn->txnFrame); 67 | } 68 | 69 | memset(txn, 0, sizeof(Txn)); 70 | 71 | slot.bits = txnId.bits; 72 | addSlotToFrame(db, &database(db)->freeTxn[txn->set][Txn_id], slot.bits); 73 | return OK; 74 | } 75 | 76 | Status txnCommit(DbMap *db, uint64_t txnBits) { 77 | uint64_t addr; 78 | DocId txnId; 79 | Txn *txn; 80 | 81 | txnId.bits = txnBits; 82 | txn = fetchIdSlot(db, txnId); 83 | addr = txn->txnFrame->bits; 84 | 85 | while (addr) { 86 | Frame *frame = getObj(db, *txn->txnFrame); 87 | while (txn->txnFrame->nslot) 88 | addSlotToFrame(db, &database(db)->freeTxn[txn->set][Txn_step], frame->slots[--txn->txnFrame->nslot].bits); 89 | 90 | addr = frame->next.bits; 91 | returnFreeFrame(db, *txn->txnFrame); 92 | } 93 | 94 | memset(txn, 0, sizeof(Txn)); 95 | 96 | addSlotToFrame(db, &database(db)->freeTxn[txn->set][Txn_id], txnId.bits); 97 | return OK; 98 | } 99 | -------------------------------------------------------------------------------- /speed5.js: -------------------------------------------------------------------------------- 1 | var count = 0; 2 | var idx; 3 | 4 | var txn; 5 | var start = new Date(); 6 | 7 | var db, dbname; 8 | 9 | for (dbname in catalog.db) 10 | db = new Db(dbname), db.drop(); 11 | 12 | db = new Db("tstdb", {onDisk:true}); 13 | 14 | var store = db.createDocStore("collection", {onDisk:true}); 15 | var index = store.createIndex("speedIdx", {onDisk:true, idxType:1}, {doc:"fwd:dbl"}); 16 | 17 | while(count<1000) { 18 | txn = new Txn(); 19 | var id, cnt; 20 | idx = 0; 21 | var docIds = []; 22 | 23 | txn = new Txn(); 24 | var array = [], key = [], keys; 25 | 26 | while(idx<1000) { 27 | // print ("batch: ", count, " item: ", idx); 28 | array = { 29 | doc : Math.random() * (count * 1000 + idx), 30 | cnt : count, 31 | idx : idx, 32 | /* text0 : "This is a test string designed to make this record bigger0", 33 | text1 : "This is a test string designed to make this record bigger1", 34 | text2 : "This is a test string designed to make this record bigger2", 35 | text3 : "This is a test string designed to make this record bigger3", 36 | text4 : "This is a test string designed to make this record bigger4", 37 | text5 : "This is a test string designed to make this record bigger5", 38 | text6 : "This is a test string designed to make this record bigger6", 39 | text7 : "This is a test string designed to make this record bigger7", 40 | text8 : "This is a test string designed to make this record bigger8", 41 | text9 : "This is a test string designed to make this record bigger9" 42 | */ }; 43 | idx += 1; 44 | } 45 | 46 | docIds = txn(store.append(array)); 47 | var nxt; 48 | 49 | for( idx = 0; idx<1000;idx++) { 50 | keys = index.buildKey(docIds[idx], array[idx].doc); 51 | for( nxt = 0; nxt < keys.length; nxt++ ) 52 | txn.index.insertKey(docIds[idx], keys[nxt++]); 53 | } 54 | 55 | print("keys:", keys, " docId: ", docIds[idx - 1]); 56 | 57 | txn.commit(); 58 | count += 1; 59 | // print ("batch: ", count); 60 | } 61 | 62 | var stop = new Date(); 63 | var ins = (stop - start) / 1000.; 64 | start = stop; 65 | 66 | var cursor, doc; 67 | 68 | cursor = index.createCursor(); 69 | 70 | var reccnt = 0; 71 | var prev = 0; 72 | 73 | while( doc = cursor.move(CursorOp.opNext)) { 74 | if (!(reccnt % 2500)) 75 | print("idx: ", reccnt, " docId: ", doc.docId, "\tkey: ", doc.doc); 76 | if (doc.doc < prev) 77 | print ("out of order record #", reccnt, "\tkey: ", doc.doc, " prev: ", prev); 78 | 79 | prev = doc.doc; 80 | reccnt += 1; 81 | } 82 | 83 | var stop = new Date(); 84 | 85 | print ("insert: ", ins, " seconds"); 86 | print ("found: ", reccnt, " should be 1000000"); 87 | print ("sort verify: ", (stop - start) / 1000., " seconds"); 88 | -------------------------------------------------------------------------------- /sunspider/3d-morph.js: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2007 Apple Inc. All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions 6 | // are met: 7 | // 1. Redistributions of source code must retain the above copyright 8 | // notice, this list of conditions and the following disclaimer. 9 | // 2. Redistributions in binary form must reproduce the above copyright 10 | // notice, this list of conditions and the following disclaimer in the 11 | // documentation and/or other materials provided with the distribution. 12 | // 13 | // THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY 14 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 | // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR 17 | // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 18 | // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 19 | // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 20 | // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 21 | // OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 | // 25 | 26 | jsdb_setOption("Math"); 27 | 28 | var loops = 15; 29 | var nx = 120; 30 | var nz = 120; 31 | 32 | function morph(a, f) { 33 | var PI2nx = Math.PI * 8/nx; 34 | var sin = Math.sin; 35 | var f30 = -(50 * sin(f*Math.PI*2)); 36 | 37 | for (var i = 0; i < nz; ++i) { 38 | for (var j = 0; j < nx; ++j) { 39 | a[3*(i*nx+j)+1] = sin((j-1) * PI2nx ) * -f30; 40 | } 41 | } 42 | } 43 | 44 | 45 | var a = Array(nx*nz*3); 46 | 47 | for (var i=0; i < nx*nz*3; ++i) 48 | a[i] = 0; 49 | 50 | for (var i = 0; i < loops; ++i) { 51 | morph(a, i/loops); 52 | } 53 | 54 | var testOutput = 0; 55 | 56 | for (var i = 0; i < nx; i++) 57 | testOutput += a[3*(i*nx+i)+1]; 58 | 59 | a = null; 60 | 61 | // This has to be an approximate test since ECMAscript doesn't formally specify 62 | // what sin() returns. Even if it did specify something like for example what Java 7 63 | // says - that sin() has to return a value within 1 ulp of exact - then we still 64 | // would not be able to do an exact test here since that would allow for just enough 65 | // low-bit slop to create possibly big errors due to testOutput being a sum. 66 | 67 | var epsilon = 1e-13; 68 | 69 | if (Math.abs(testOutput) >= epsilon) 70 | print("Error: bad test output: expected magnitude below " + epsilon + " but got " + testOutput); 71 | else 72 | print("Success: ", testOutput); 73 | -------------------------------------------------------------------------------- /tests.bat: -------------------------------------------------------------------------------- 1 | mkdir dbdata 2 | jsdb.exe -MallocDebug system*.js jsscripts/test_aes3.js 3 | jsdb.exe -MallocDebug system*.js jsscripts/test_args.js 4 | jsdb.exe -MallocDebug system*.js jsscripts/test_array.js 5 | jsdb.exe -MallocDebug system*.js jsscripts/test_assign.js 6 | jsdb.exe -MallocDebug system*.js jsscripts/test_bin.js 7 | jsdb.exe -MallocDebug system*.js jsscripts/test_comment.js 8 | jsdb.exe -MallocDebug system*.js jsscripts/test_comp.js 9 | jsdb.exe -MallocDebug system*.js jsscripts/test_concat.js 10 | jsdb.exe -MallocDebug system*.js jsscripts/test_conv.js 11 | jsdb.exe -MallocDebug system*.js jsscripts/test_cube.js 12 | jsdb.exe -MallocDebug system*.js jsscripts/test_date.js 13 | jsdb.exe -MallocDebug system*.js jsscripts/test_db.js 14 | jsdb.exe -MallocDebug system*.js jsscripts/test_dbartree.js 15 | jsdb.exe -MallocDebug system*.js jsscripts/test_dbbtree.js 16 | jsdb.exe -MallocDebug system*.js jsscripts/test_dbdocs.js 17 | jsdb.exe -MallocDebug system*.js jsscripts/test_dbidx.js 18 | jsdb.exe -MallocDebug system*.js jsscripts/test_dbtxn.js 19 | jsdb.exe -MallocDebug system*.js jsscripts/test_dbupdate.js 20 | jsdb.exe -MallocDebug system*.js jsscripts/test_enum.js 21 | jsdb.exe -MallocDebug system*.js jsscripts/test_es6scope.js 22 | jsdb.exe -MallocDebug system*.js jsscripts/test_fcn2.js 23 | jsdb.exe -MallocDebug system*.js jsscripts/test_fcn.js 24 | jsdb.exe -MallocDebug system*.js jsscripts/test_for.js 25 | jsdb.exe -MallocDebug system*.js jsscripts/test_ftw.js 26 | jsdb.exe -MallocDebug system*.js jsscripts/test_ifthenelse.js 27 | jsdb.exe -MallocDebug system*.js jsscripts/test_int.js 28 | jsdb.exe -MallocDebug system*.js jsscripts/test_json.js 29 | jsdb.exe -MallocDebug system*.js jsscripts/test_math.js 30 | jsdb.exe -MallocDebug system*.js jsscripts/test_name.js 31 | jsdb.exe -MallocDebug system*.js jsscripts/test_num32.js 32 | jsdb.exe -MallocDebug system*.js jsscripts/test_num64.js 33 | jsdb.exe -MallocDebug system*.js jsscripts/test_num.js 34 | jsdb.exe -MallocDebug system*.js jsscripts/test_obj.js 35 | jsdb.exe -MallocDebug system*.js jsscripts/test_parse.js 36 | jsdb.exe -MallocDebug system*.js jsscripts/test_props.js 37 | jsdb.exe -MallocDebug system*.js jsscripts/test_proto.js 38 | jsdb.exe -MallocDebug system*.js jsscripts/test_ray.js 39 | jsdb.exe -MallocDebug system*.js jsscripts/test_rel.js 40 | jsdb.exe -MallocDebug system*.js jsscripts/test_semi.js 41 | jsdb.exe -MallocDebug system*.js jsscripts/test_sort.js 42 | jsdb.exe -MallocDebug system*.js jsscripts/test_str1.js 43 | jsdb.exe -MallocDebug system*.js jsscripts/test_str.js 44 | jsdb.exe -MallocDebug system*.js jsscripts/test_tern.js 45 | jsdb.exe -MallocDebug system*.js jsscripts/test_this.js 46 | jsdb.exe -MallocDebug system*.js jsscripts/test_toks.js 47 | jsdb.exe -MallocDebug system*.js jsscripts/test_var.js 48 | jsdb.exe -MallocDebug system*.js jsscripts/test_xtn.js 49 | -------------------------------------------------------------------------------- /speed3.js: -------------------------------------------------------------------------------- 1 | var count = 0; 2 | var idx; 3 | 4 | var txn; 5 | var start = new Date(); 6 | 7 | var db, dbname; 8 | 9 | for (dbname in catalog.db) 10 | db = new Db(dbname), db.drop(); 11 | 12 | db = new Db("tstdb", {onDisk:true}); 13 | 14 | var store = db.createDocStore("collection", {onDisk:true}); 15 | var index = store.createIndex("speedIdx", {onDisk:true, idxType:0}, {doc:"fwd:dbl"}); 16 | 17 | while(count<1000) { 18 | var id, cnt; 19 | idx = 0; 20 | var docIds = []; 21 | 22 | // txn = jsdb_beginTxn(); 23 | var array = [], key; 24 | 25 | while(idx<1000) { 26 | // print ("batch: ", count, " item: ", idx); 27 | array[idx] = { 28 | doc : Math.random() * (count * 1000 + idx), 29 | cnt : count, 30 | idx : idx, 31 | /* text0 : "This is a test string designed to make this record bigger0", 32 | text1 : "This is a test string designed to make this record bigger1", 33 | text2 : "This is a test string designed to make this record bigger2", 34 | text3 : "This is a test string designed to make this record bigger3", 35 | text4 : "This is a test string designed to make this record bigger4", 36 | text5 : "This is a test string designed to make this record bigger5", 37 | text6 : "This is a test string designed to make this record bigger6", 38 | text7 : "This is a test string designed to make this record bigger7", 39 | text8 : "This is a test string designed to make this record bigger8", 40 | text9 : "This is a test string designed to make this record bigger9" 41 | */ }; 42 | idx += 1; 43 | } 44 | 45 | docIds = store.writeDocs(array); 46 | var nxt; 47 | 48 | for( idx = 0; idx<1000;idx++) { 49 | // keys = index.buildKey(docIds[idx], array[idx].doc); 50 | // for( nxt = 0; nxt < keys.length; nxt++ ) 51 | key = index.insertKey(docIds[idx], array[idx].doc); 52 | } 53 | 54 | print("key: [", key, "] docId: ", docIds[idx - 1]); 55 | 56 | // jsdb_commitTxn(); 57 | count += 1; 58 | // print ("batch: ", count); 59 | } 60 | 61 | var stop = new Date(); 62 | var ins = (stop - start) / 1000.; 63 | start = stop; 64 | 65 | var cursor, doc; 66 | 67 | cursor = index.createCursor(); 68 | 69 | var reccnt = 0; 70 | var prev = 0; 71 | var docId; 72 | 73 | while( docId = cursor.move(CursorOp.opNext)) { 74 | key = cursor.keyAt(); 75 | 76 | if (!(reccnt % 2500)) 77 | print("docId: ", docId, "\tkey: [", key, "]"); 78 | if ( key < prev) 79 | print ("out of order record #", reccnt, " docId: ", doc.docId, "\tkey: ", key, " prev: ", prev); 80 | 81 | prev = key; 82 | reccnt += 1; 83 | } 84 | 85 | var stop = new Date(); 86 | 87 | print ("insert: ", ins, " seconds"); 88 | print ("found: ", reccnt, " should be 1000000"); 89 | print ("sort verify: ", (stop - start) / 1000., " seconds"); 90 | -------------------------------------------------------------------------------- /speed4.js: -------------------------------------------------------------------------------- 1 | var count = 0; 2 | var idx; 3 | 4 | var txn; 5 | var start = new Date(); 6 | 7 | var db, dbname; 8 | 9 | for (dbname in catalog.db) 10 | db = new Db(dbname), db.drop(); 11 | 12 | db = new Db("tstdb", {onDisk:true}); 13 | 14 | var store = db.createDocStore("collection", {onDisk:true, recordType:1}); 15 | var index = store.createIndex("speedIdx", {onDisk:true, idxType:1}, {doc:"fwd:dbl"}); 16 | 17 | while(count<1000) { 18 | var txn, id, cnt; 19 | idx = 0; 20 | var docIds = []; 21 | 22 | txn = new Txn(); 23 | var array = [], key; 24 | 25 | while(idx<1000) { 26 | // print ("batch: ", count, " item: ", idx); 27 | array[idx] = { 28 | doc : Math.random() * (count * 1000 + idx), 29 | cnt : count, 30 | idx : idx, 31 | /* text0 : "This is a test string designed to make this record bigger0", 32 | text1 : "This is a test string designed to make this record bigger1", 33 | text2 : "This is a test string designed to make this record bigger2", 34 | text3 : "This is a test string designed to make this record bigger3", 35 | text4 : "This is a test string designed to make this record bigger4", 36 | text5 : "This is a test string designed to make this record bigger5", 37 | text6 : "This is a test string designed to make this record bigger6", 38 | text7 : "This is a test string designed to make this record bigger7", 39 | text8 : "This is a test string designed to make this record bigger8", 40 | text9 : "This is a test string designed to make this record bigger9" 41 | */ }; 42 | idx += 1; 43 | } 44 | 45 | docIds = txn.write(index, store, array); 46 | var nxt; 47 | 48 | for( idx = 0; idx<1000;idx++) { 49 | // keys = index.buildKey(docIds[idx], array[idx].doc); 50 | // for( nxt = 0; nxt < keys.length; nxt++ ) 51 | key = index.insertKey(docIds[idx], array[idx].doc); 52 | } 53 | 54 | print("key: [", key, "] docId: ", docIds[idx - 1]); 55 | 56 | txn.commit(); 57 | count += 1; 58 | // print ("batch: ", count); 59 | } 60 | 61 | var stop = new Date(); 62 | var ins = (stop - start) / 1000.; 63 | start = stop; 64 | 65 | var cursor, doc, docId; 66 | 67 | cursor = index.createCursor(); 68 | print("begin cursor scan"); 69 | // cursor.move(CursorOp.opLeft); 70 | 71 | var reccnt = 0; 72 | var prev = 0; 73 | 74 | while( docId = cursor.move(CursorOp.opNext)) { 75 | key = cursor.keyAt(); 76 | // if (!(reccnt % 2500)) 77 | print("idx: ", reccnt, " docId: ", docId, "\tkey: [", key, "]"); 78 | if (doc.doc < prev) 79 | print ("out of order record #", reccnt, "\tkey: [", key, "] prev: ", prev); 80 | 81 | prev = key; 82 | reccnt += 1; 83 | } 84 | 85 | var stop = new Date(); 86 | 87 | print ("insert: ", ins, " seconds"); 88 | print ("found: ", reccnt, " should be 1000000"); 89 | print ("sort verify: ", (stop - start) / 1000., " seconds"); 90 | -------------------------------------------------------------------------------- /oldjsdb/jsdb_rwlock.c: -------------------------------------------------------------------------------- 1 | #ifdef linux 2 | #define _GNU_SOURCE 3 | #include 4 | #endif 5 | 6 | #ifndef _WIN32 7 | #include 8 | #endif 9 | 10 | #include "jsdb.h" 11 | #include "jsdb_db.h" 12 | #include "jsdb_rwlock.h" 13 | 14 | #ifdef linux 15 | #include 16 | #include 17 | 18 | int sys_futex(void *addr1, int op, int val1, struct timespec *timeout, void *addr2, int val3) 19 | { 20 | return syscall(SYS_futex, addr1, op, val1, timeout, addr2, val3); 21 | } 22 | #endif 23 | 24 | void bt_mutexlock(Mutex *latch) 25 | { 26 | uint32_t idx, waited = 0; 27 | Mutex prev[1]; 28 | 29 | while( 1 ) { 30 | for( idx = 0; idx < 100; idx++ ) { 31 | #ifndef _WIN32 32 | *prev->value = __sync_fetch_and_or (latch->value, 1); 33 | #else 34 | *prev->value = InterlockedOr (latch->value, 1); 35 | #endif 36 | if( !*prev->bits->xcl ) { 37 | if( waited ) 38 | #ifndef _WIN32 39 | __sync_fetch_and_sub (latch->bits->waiters, 1); 40 | #else 41 | InterlockedDecrement16 (latch->bits->waiters); 42 | #endif 43 | return; 44 | } 45 | } 46 | 47 | if( !waited ) { 48 | #ifndef _WIN32 49 | __sync_fetch_and_add (latch->bits->waiters, 1); 50 | #else 51 | _InterlockedIncrement16 (latch->bits->waiters); 52 | #endif 53 | *prev->bits->waiters += 1; 54 | waited++; 55 | } 56 | 57 | #ifdef linux 58 | sys_futex (latch->value, FUTEX_WAIT, *prev->value, NULL, NULL, 0); 59 | #elif defined(_WIN32) 60 | SwitchToThread(); 61 | #else 62 | sched_yield(); 63 | #endif 64 | } 65 | } 66 | 67 | void bt_releasemutex(Mutex *latch) 68 | { 69 | Mutex prev[1]; 70 | 71 | #ifndef _WIN32 72 | *prev->value = __sync_fetch_and_and (latch->value, 0xffff0000); 73 | #else 74 | *prev->value = InterlockedAnd (latch->value, 0xffff0000); 75 | #endif 76 | 77 | if( *prev->bits->waiters ) 78 | #ifdef linux 79 | sys_futex( latch->value, FUTEX_WAKE, 1, NULL, NULL, 0 ); 80 | #elif defined(_WIN32) 81 | SwitchToThread(); 82 | #else 83 | sched_yield(); 84 | #endif 85 | } 86 | 87 | // reader/writer lock implementation 88 | 89 | void writeLock (RWLock *lock) 90 | { 91 | bt_mutexlock (lock->xcl); 92 | bt_mutexlock (lock->wrt); 93 | lock->type = 1; 94 | bt_releasemutex (lock->xcl); 95 | } 96 | 97 | void rwUnlock (RWLock *lock) 98 | { 99 | if (lock->type) { 100 | bt_releasemutex (lock->wrt); 101 | return; 102 | } 103 | 104 | #ifndef _WIN32 105 | if( __sync_fetch_and_sub (&lock->readers, 1) == 1 ) 106 | #else 107 | if( !InterlockedDecrement16 (&lock->readers) ) 108 | #endif 109 | bt_releasemutex (lock->wrt); 110 | } 111 | 112 | void readLock (RWLock *lock) 113 | { 114 | bt_mutexlock (lock->xcl); 115 | 116 | #ifndef _WIN32 117 | if( !__sync_fetch_and_add (&lock->readers, 1) ) 118 | #else 119 | if( !(InterlockedIncrement16 (&lock->readers)-1) ) 120 | #endif 121 | bt_mutexlock (lock->wrt); 122 | 123 | lock->type = 0; 124 | bt_releasemutex (lock->xcl); 125 | } 126 | -------------------------------------------------------------------------------- /oldjsdb/jsdb_dbbtreecursor.c: -------------------------------------------------------------------------------- 1 | #include "jsdb.h" 2 | #include "jsdb_db.h" 3 | 4 | uint64_t btreeDocId(BtreeCursor *cursor) { 5 | uint8_t *ptr = keyptr(cursor->page, cursor->slotIdx); 6 | KeySuffix *suffix = (KeySuffix *)(ptr + keypre(ptr) + keylen(ptr) - sizeof(KeySuffix)); 7 | return get64(suffix->docId); 8 | } 9 | 10 | value_t btreeCursor(value_t hndl, DbMap *index, bool reverse, value_t fields, value_t limits) { 11 | BtreeCursor *cursor; 12 | BtreeIndex *btree; 13 | BtreePage *page; 14 | value_t val; 15 | 16 | btree = btreeIndex(index); 17 | 18 | val.bits = vt_handle; 19 | val.subType = Hndl_btreeCursor; 20 | val.handle = jsdb_alloc(sizeof(BtreeCursor), true); 21 | val.refcount = 1; 22 | incrRefCnt(val); 23 | 24 | cursor = val.handle; 25 | cursor->hdr->hndl = hndl; 26 | cursor->hdr->pqAddr.bits = addPQEntry(index, getSet(index), en_reader); 27 | cursor->hdr->timestamp = getTimestamp(index, cursor->hdr->pqAddr); 28 | 29 | cursor->pageAddr.bits = jsdb_rawalloc(btree->pageSize << btree->leafXtra, false); 30 | cursor->page = jsdb_rawaddr(cursor->pageAddr.bits); 31 | 32 | if (!reverse) { 33 | page = getObj(index, btree->leaf); 34 | memcpy (cursor->page, page, btree->pageSize << btree->leafXtra); 35 | cursor->slotIdx = 0; 36 | } 37 | 38 | return val; 39 | } 40 | 41 | KeySuffix *btreeCursorSuffix(BtreeCursor *cursor) { 42 | uint8_t *key = keyptr(cursor->page, cursor->slotIdx); 43 | uint32_t len = keylen(key); 44 | 45 | return (KeySuffix *)(key + keypre(key) + len - sizeof(KeySuffix)); 46 | } 47 | 48 | value_t btreeCursorKey(BtreeCursor *cursor) { 49 | uint8_t *key = keyptr(cursor->page, cursor->slotIdx); 50 | value_t val; 51 | 52 | val.bits = vt_string; 53 | val.aux = keylen(key); 54 | val.str = key + keypre(key); 55 | return val; 56 | } 57 | 58 | bool btreeSeekKey (BtreeCursor *cursor, DbMap *index, uint8_t *key, uint32_t keylen) { 59 | return true; 60 | } 61 | 62 | uint64_t btreeNextKey (BtreeCursor *cursor, DbMap *index) { 63 | BtreeIndex *btree = btreeIndex(index); 64 | BtreePage *page; 65 | 66 | while (true) { 67 | uint32_t max = cursor->page->cnt; 68 | 69 | if (!cursor->page->right.bits) 70 | max--; 71 | 72 | while (cursor->slotIdx < max) 73 | if (slotptr(cursor->page, ++cursor->slotIdx)->dead) 74 | continue; 75 | else 76 | return btreeDocId(cursor); 77 | 78 | if (cursor->page->right.bits) 79 | page = getObj(index, cursor->page->right); 80 | else 81 | return 0; 82 | 83 | memcpy (cursor->page, page, btree->pageSize << btree->leafXtra); 84 | cursor->slotIdx = 0; 85 | } 86 | } 87 | 88 | uint64_t btreePrevKey (BtreeCursor *cursor, DbMap *index) { 89 | BtreeIndex *btree = btreeIndex(index); 90 | BtreePage *page; 91 | 92 | while (true) { 93 | if (cursor->slotIdx) { 94 | if (slotptr(cursor->page, --cursor->slotIdx)->dead) 95 | continue; 96 | else 97 | return btreeDocId(cursor); 98 | } 99 | 100 | if (cursor->page->left.bits) 101 | page = getObj(index, cursor->page->left); 102 | else 103 | return 0; 104 | 105 | memcpy (cursor->page, page, btree->pageSize << btree->leafXtra); 106 | cursor->slotIdx = cursor->page->cnt; 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /jsscripts/test_dbidx.js: -------------------------------------------------------------------------------- 1 | print("\n\nbegin test_dbidx.js"); 2 | print("------------------"); 3 | print("The database creator: ", Db); 4 | 5 | var db, dbname; 6 | 7 | for (dbname in catalog.db) 8 | db = new Db(dbname), db.drop(); 9 | 10 | var ver, cnt; 11 | var dbops = {onDisk:true}; 12 | db = new Db("testing", dbops); 13 | 14 | print("Handle for: ", db); 15 | 16 | var store = db.createDocStore("docStore", {onDisk:true}); 17 | 18 | print("Handle for: ", store); 19 | 20 | var PrimaryIdx = store.createIndex("PrimaryIdx", {onDisk:true}, {b:"fwd:int"}); 21 | var SecondIdx = store.createIndex("SecondIdx", {onDisk:true}, {a:"fwd:dbl"}); 22 | var ThirdIdx = store.createIndex("ThirdIdx", {onDisk:true}, {x:"fwd:string"}); 23 | var FourthIdx = store.createIndex("FourthIdx", {onDisk:true}, {"c.d":"fwd:string"}); 24 | var FifthIdx = store.createIndex("FifthIdx", {onDisk:true}, {"yy":"fwd:string"}); 25 | 26 | print("Handle: ", PrimaryIdx); 27 | print("Handle: ", SecondIdx); 28 | print("Handle: ", ThirdIdx); 29 | print("Handle: ", FourthIdx); 30 | print("Handle: ", FifthIdx); 31 | 32 | print("\nstoring documents: ",{a:1.0, b:2, c: {d:"B", e:"F"}, x:"alpha0"}); 33 | 34 | var doc = store.insert({a:1.0, b:2, c: {d:"A", e:"F"}, x:"alpha3"}); 35 | print("recordId for insert of a:1.0, b:2, c.d:A x:alpha3: ", doc.docId); 36 | 37 | doc = store.insert({a:1.2, b:3, c: {d:"Z", e:"F"}, x:"alpha9"}); 38 | print("recordId for insert of a:1.2, b:3, c.d:Z x:alpha9: ", doc.docId); 39 | 40 | doc = store.insert({a:1.1, b:1, c: {d:"M", e:"F"}, x:"alpha0"}); 41 | print("recordId for insert of a:1.1, b:1, c.d:M x:alpha0: ", doc.docId); 42 | 43 | var cursor1 = PrimaryIdx.createCursor({deDup:true}); 44 | 45 | print("\ndocuments forward sorted by field b"); 46 | cursor1.move(CursorOp.opLeft); 47 | 48 | while (doc = cursor1.next()) 49 | print (doc.docId, "\t", doc); 50 | 51 | print("\ndocuments reverse sorted by field b"); 52 | cursor1.move(CursorOp.opRight); 53 | 54 | while (doc = cursor1.prev()) 55 | print (doc.docId, "\t", doc); 56 | 57 | var cursor2 = SecondIdx.createCursor(); 58 | 59 | print("\ndocuments forward sorted by field a"); 60 | cursor2.move(CursorOp.opLeft); 61 | 62 | while (doc = cursor2.next()) 63 | print (doc.docId, "\t", doc); 64 | 65 | print("\ndocuments reverse sorted by field a"); 66 | cursor2.move(CursorOp.opRight); 67 | 68 | while (doc = cursor2.prev()) 69 | print (doc.docId, "\t", doc); 70 | 71 | var cursor3 = ThirdIdx.createCursor(); 72 | 73 | print("\ndocuments forward sorted by field x"); 74 | cursor3.move(CursorOp.opLeft); 75 | 76 | while (doc = cursor3.next()) 77 | print (doc.docId, "\t", doc); 78 | 79 | print("\ndocuments reverse sorted by field x"); 80 | cursor3.move(CursorOp.opRight); 81 | 82 | while (doc = cursor3.prev()) 83 | print (doc.docId, "\t", doc); 84 | 85 | var cursor4 = FourthIdx.createCursor(); 86 | var doc; 87 | 88 | print("\ndocuments forward sorted by field c.d"); 89 | cursor4.move(CursorOp.opLeft); 90 | 91 | while (doc = cursor4.next()) 92 | print (doc.docId, "\t", doc); 93 | 94 | print("\ndocuments reverse sorted by field c.d"); 95 | cursor4.move(CursorOp.opRight); 96 | 97 | while (doc = cursor4.prev()) 98 | print (doc.docId, "\t", doc); 99 | 100 | -------------------------------------------------------------------------------- /sunspider/math-cordic.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) Rich Moore. All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions 6 | * are met: 7 | * 1. Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * 2. Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * 13 | * THIS SOFTWARE IS PROVIDED BY CONTRIBUTORS ``AS IS'' AND ANY 14 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR 17 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 18 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 19 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 20 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 21 | * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 | */ 25 | 26 | jsdb_setOption("Math"); 27 | 28 | /////. Start CORDIC 29 | 30 | var AG_CONST = 0.6072529350; 31 | 32 | function FIXED(X) 33 | { 34 | return X * 65536.0; 35 | } 36 | 37 | function FLOAT(X) 38 | { 39 | return X / 65536.0; 40 | } 41 | 42 | function DEG2RAD(X) 43 | { 44 | return 0.017453 * (X); 45 | } 46 | 47 | var Angles = [ 48 | FIXED(45.0), FIXED(26.565), FIXED(14.0362), FIXED(7.12502), 49 | FIXED(3.57633), FIXED(1.78991), FIXED(0.895174), FIXED(0.447614), 50 | FIXED(0.223811), FIXED(0.111906), FIXED(0.055953), 51 | FIXED(0.027977) 52 | ]; 53 | 54 | var Target = 28.027; 55 | 56 | function cordicsincos(Target) { 57 | var X; 58 | var Y; 59 | var TargetAngle; 60 | var CurrAngle; 61 | var Step; 62 | 63 | X = FIXED(AG_CONST); /* AG_CONST * cos(0) */ 64 | Y = 0; /* AG_CONST * sin(0) */ 65 | 66 | TargetAngle = FIXED(Target); 67 | CurrAngle = 0; 68 | for (Step = 0; Step < 12; Step++) { 69 | var NewX; 70 | if (TargetAngle > CurrAngle) { 71 | NewX = X - (Y >> Step); 72 | Y = (X >> Step) + Y; 73 | X = NewX; 74 | CurrAngle += Angles[Step]; 75 | } else { 76 | NewX = X + (Y >> Step); 77 | Y = -(X >> Step) + Y; 78 | X = NewX; 79 | CurrAngle -= Angles[Step]; 80 | } 81 | } 82 | 83 | return FLOAT(X) * FLOAT(Y); 84 | } 85 | 86 | ///// End CORDIC 87 | 88 | var total = 0; 89 | 90 | function cordic( runs ) { 91 | for ( var i = 0 ; i < runs ; i++ ) { 92 | total += cordicsincos(Target); 93 | } 94 | } 95 | 96 | cordic(25000); 97 | 98 | var expected = 10362.570468755888; 99 | 100 | if (total != expected) 101 | print( "ERROR: bad result: expected ", expected, " but got ", total); 102 | else 103 | print("OK"); 104 | 105 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | Javascript-database 2 | =================== 3 | 4 | A working project for High-performance javascript interpreter with built-in NO-SQL document store source code in C. The database operations are performed directly from a javascript dialect program, or submitted over tcp connections from mongo shells, or node.js connections. 5 | 6 | ``` 7 | git clone --recursive git://github.com/malbrain/javascript-database 8 | ``` 9 | Download latest commits (after cloning): 10 | 11 | ``` 12 | git pull 13 | git submodule update --remote --recursive 14 | ``` 15 | 16 | Compilation is achieved on 64 bit linux: 17 | 18 | ``` 19 | bison -d -v -Wall js.y 20 | flex -f js.l 21 | gcc -std=gnu99 -Wall -Wshadow -Wpointer-arith -Wstrict-prototypes -O2 -ggdb -o jsdb -fno-omit-frame- pointer js*.c lex.yy.c database/db*.c database/btree1/*.c database/artree/*.c database/btree2/*.c -lm -lpthread -Wl ,-Map=jsdb.map 22 | ``` 23 | For 64 bit Windows: (be sure to use win_bison version 3.0.4) The win_bison and win_flex executables are included, along with a compressed file containing the data subdirectory for extraction. 24 | 25 | ``` 26 | win_bison.exe --output="js.tab.c" --defines="js.tab.h" --debug --verbose --warnings=all --report=state --report-file="js.tab.output" "js.y" 27 | win_flex.exe --wincompat -B -R -f --outfile="js.lex.c" js.l 28 | cl /W3 /Oi /Ox /Z7 /Fejsdb.exe js*.c database/db_*.c database/btree2/btree2*.c database/btree1/btree1*.c database/artree/artree*.c wsock32.lib /Fm /link ./setargv.obj 29 | ``` 30 | The software also runs on the Windows Subsystem Linux (WSL) and compiles under WSL using the build.wsl bash script. 31 | 32 | Supplied are many javascript programs to run. The first ones are speed1.js and speed2.js which each write 1000000 documents into a collection. speed1.js writes only the document, while speed2.js adds a random index key value to each document: 33 | 34 | ``` 35 | D:\github\javascript-database>del dbdata 36 | D:\github\javascript-database\dbdata\*, Are you sure (Y/N)? y 37 | 38 | D:\github\javascript-database>jsdb system*.js speed1.js 39 | insert: 2.166 seconds 40 | found: 1000000 should be 1000000 41 | scan verify: 0.736 seconds 42 | 43 | D:\github\javascript-database>del dbdata 44 | D:\github\javascript-database\dbdata\*, Are you sure (Y/N)? y 45 | 46 | D:\github\javascript-database>jsdb system*.js speed2.js 47 | insert: 3.469 seconds 48 | found: 1000000 should be 1000000 49 | sort verify: 1.501 seconds 50 | ``` 51 | The tcp server for mongo shell clients is launched on port 27017 by running: 52 | 53 | ``` 54 | jsdb system*.js mongo*.js 55 | ``` 56 | Otherwise, a javaScript file will run with arguments: 57 | 58 | ``` 59 | jsdb -opt1 -opt2 system*.js yourfile.js -- yourarg1 yourarg2 yourarg3 ... 60 | ``` 61 | The mongod.js server program is under developement. You can experiment with collection indexing, saving, and sorting from the mongo shell. The collection.createIndex sample call: t.createIndex({field:1}, {type:"art"}); the save command: t.save({field:1}); and a sample find().sort() call: t.find().sort({index: "field_1", start:[composit flds ,...], limit:[composit flds...]}); 62 | 63 | A mongo direct interface that implements mongo shell commands directly on the server without BSON or a TCP connection: 64 | 65 | ``` 66 | jsdb system*.js jsDb*.js test_mongo.js 67 | ``` 68 | Please address any concerns, bug reports, or questions to the author: malbrain@cal.berkeley.edu. 69 | 70 | -------------------------------------------------------------------------------- /oldjsdb/jsdb_dbpq.c: -------------------------------------------------------------------------------- 1 | #include "jsdb.h" 2 | #include "jsdb_db.h" 3 | #include "jsdb_dbpq.h" 4 | 5 | // reader == even 6 | 7 | bool isReader(uint64_t ts) { 8 | return !(ts & 1); 9 | } 10 | 11 | // writer == odd 12 | 13 | bool isWriter(uint64_t ts) { 14 | return (ts & 1); 15 | } 16 | 17 | // committed == not reader 18 | 19 | bool isCommitted(uint64_t ts) { 20 | return (ts & 1); 21 | } 22 | 23 | void computePQMin(DbPQ *pq) { 24 | uint64_t min = 0; 25 | uint32_t i; 26 | 27 | lockLatch(pq->mutex); 28 | min--; 29 | 30 | for (i=0; i < pq->cpuCount; ++i) { 31 | if (pq->entryLists[i].minValue) 32 | if (min > pq->entryLists[i].minValue) 33 | min = pq->entryLists[i].minValue; 34 | } 35 | 36 | pq->globalMin = min; 37 | unlockLatch(pq->mutex); 38 | } 39 | 40 | uint64_t getTimestamp(DbMap *map, DbAddr addr) { 41 | PQEntry *entry = getObj(map->db, addr); 42 | 43 | return entry->value; 44 | } 45 | 46 | uint64_t allocateTimestamp(DbMap *map, enum ReaderWriterEnum e) { 47 | DataBase *db = database(map->db); 48 | uint64_t ts; 49 | 50 | ts = *db->pq->pqTime; 51 | 52 | if (!ts) 53 | ts = atomicAdd64(db->pq->pqTime, 1); 54 | 55 | switch (e) { 56 | case en_minimum: 57 | ts = db->pq->globalMin; 58 | break; 59 | 60 | case en_reader: 61 | while (!isReader(ts)) 62 | ts = atomicAdd64(db->pq->pqTime, 1); 63 | break; 64 | case en_writer: 65 | while (!isWriter(ts)) 66 | ts = atomicAdd64(db->pq->pqTime, 1); 67 | break; 68 | 69 | default: break; 70 | } 71 | 72 | return ts; 73 | } 74 | 75 | uint64_t addPQEntry(DbMap *map, uint32_t set, enum ReaderWriterEnum e) { 76 | DataBase *db = database(map->db); 77 | PQEntry *entry; 78 | DbAddr addr; 79 | 80 | lockLatch((char *)db->pq->entryLists[set].mutex); 81 | 82 | if ((addr.bits = allocObj(map->db, db->freePQ, 0, sizeof(PQEntry), true) )) 83 | entry = getObj(map->db, addr); 84 | else 85 | return 0; 86 | 87 | entry->value = allocateTimestamp(map->db, e); 88 | entry->prev.bits = 0; 89 | entry->set = set; 90 | 91 | if ( (entry->next.bits = db->pq->entryLists[set].queueHead.bits) ) { 92 | PQEntry* next = getObj(map->db, db->pq->entryLists[set].queueHead); 93 | next->prev.bits = addr.bits; 94 | } else 95 | db->pq->entryLists[set].minValue = entry->value; 96 | 97 | db->pq->entryLists[set].queueHead.bits = addr.bits; 98 | 99 | if (db->pq->globalMin > entry->value) 100 | computePQMin(db->pq); 101 | 102 | unlockLatch(db->pq->entryLists[set].mutex); 103 | return addr.bits; 104 | } 105 | 106 | void removePQEntry(DbMap *map, DbAddr addr) { 107 | DataBase *db = database(map->db); 108 | PQEntry *prev, *next, *entry; 109 | 110 | entry = getObj(map->db, addr); 111 | lockLatch(db->pq->entryLists[entry->set].mutex); 112 | 113 | prev = getObj(map->db, entry->prev); 114 | next = getObj(map->db, entry->next); 115 | 116 | if (entry->next.bits) 117 | next->prev.bits = entry->prev.bits; 118 | else if (entry->prev.bits) 119 | db->pq->entryLists[entry->set].minValue = prev->value; 120 | else 121 | db->pq->entryLists[entry->set].minValue = 0; 122 | 123 | if (entry->prev.bits) 124 | prev->next.bits = entry->next.bits; 125 | else 126 | db->pq->entryLists[entry->set].queueHead.bits = entry->next.bits; 127 | 128 | addSlotToFrame(map->db, &db->freePQ[entry->set], addr.bits); 129 | unlockLatch(db->pq->entryLists[entry->set].mutex); 130 | } 131 | -------------------------------------------------------------------------------- /mongo/js_dbinsert.c: -------------------------------------------------------------------------------- 1 | #include "js.h" 2 | #include "database/db.h" 3 | #include "database/db_api.h" 4 | 5 | extern uint32_t calcSize (value_t doc); 6 | extern void marshal_doc(value_t document, uint8_t *doc, uint32_t docSize); 7 | 8 | // insertDocs (docStore, docArray, &docIdArray, &docCount, dbTxn) 9 | 10 | value_t js_insertDocs(uint32_t args, environment_t *env) { 11 | value_t v, slot, slot2, docs, docStore, dbTxn; 12 | value_t array; 13 | uint32_t size; 14 | int i, count; 15 | value_t s; 16 | Doc *doc; 17 | 18 | s.bits = vt_status; 19 | 20 | if (debug) fprintf(stderr, "funcall : InsertDocs\n"); 21 | 22 | docStore = eval_arg (&args, env); 23 | 24 | if (vt_handle != docStore.type || Hndl_docStore != docStore.subType) { 25 | fprintf(stderr, "Error: createIndex => expecting docStore:handle => %s\n", strtype(docStore.type)); 26 | return s.status = ERROR_script_internal, s; 27 | } 28 | 29 | // insert an array of documents 30 | 31 | array = eval_arg(&args, env); 32 | 33 | if (vt_array != array.type && vt_object != array.type && vt_document != array.type) { 34 | fprintf(stderr, "Error: insertDocs => expecting docs:Array => %s\n", strtype(array.type)); 35 | return s.status = ERROR_script_internal, s; 36 | } 37 | 38 | if (array.type == vt_array) 39 | count = vec_count(array.aval->values); 40 | else 41 | count = 1; 42 | 43 | // return an array of DocId 44 | 45 | slot = eval_arg(&args, env); 46 | 47 | if (vt_lval != slot.type) { 48 | fprintf(stderr, "Error: insertDocs => expecting DocId:Symbol => %s\n", strtype(slot.type)); 49 | return s.status = ERROR_script_internal, s; 50 | } 51 | 52 | // return the size of the array 53 | 54 | slot2 = eval_arg(&args, env); 55 | 56 | if (vt_lval != slot2.type) { 57 | fprintf(stderr, "Error: insertDocs => expecting Count:Symbol => %s\n", strtype(slot2.type)); 58 | return s.status = ERROR_script_internal, s; 59 | } 60 | 61 | // insert txn 62 | 63 | dbTxn = eval_arg(&args, env); 64 | 65 | if (vt_txnId != dbTxn.type && vt_undef != dbTxn.type) { 66 | fprintf(stderr, "Error: insertDocs => expecting Txn:docId => %s\n", strtype(dbTxn.type)); 67 | return s.status = ERROR_script_internal, s; 68 | } 69 | 70 | docs = newArray(array_value); 71 | 72 | // insert the documents 73 | 74 | for( i = 0; i < count; i++ ) { 75 | value_t nxtDoc; 76 | 77 | if (array.type == vt_array) 78 | nxtDoc = array.aval->values[i]; 79 | else 80 | nxtDoc = array; 81 | 82 | // marshall the document 83 | 84 | size = calcSize(nxtDoc); 85 | 86 | if ((s.status = (int)allocDoc((DbHandle *)docStore.handle, &doc, size))) 87 | return fprintf(stderr, "Error: insertDocs => %s\n", strstatus(s.status)), s; 88 | 89 | marshal_doc(nxtDoc, (uint8_t*)(doc + 1), size); 90 | 91 | // add the document and index keys to the documentStore 92 | 93 | s.status = (int)assignDoc((DbHandle *)docStore.handle, doc, dbTxn.txnBits); 94 | 95 | if (s.status) { 96 | fprintf(stderr, "Error: insertDocs => %s\n", strstatus(s.status)); 97 | return s; 98 | } 99 | 100 | // add the docId to the result Array 101 | 102 | v.bits = vt_docId; 103 | v.docBits = doc->docId.bits; 104 | vec_push(docs.aval->values, v); 105 | } 106 | 107 | replaceValue(slot, docs); 108 | 109 | v.bits = vt_int; 110 | v.nval = count; 111 | replaceValue(slot2, v); 112 | abandonValue(array); 113 | return s.status = OK, s; 114 | } 115 | 116 | -------------------------------------------------------------------------------- /jsscripts/test_dbupdate.js: -------------------------------------------------------------------------------- 1 | print("\n\nbegin test_dbupdate.js"); 2 | print("------------------"); 3 | 4 | var db, dbname; 5 | 6 | for (dbname in catalog.db) 7 | db = new Db(dbname), db.drop(); 8 | 9 | var doc, ver, cnt; 10 | var dbops = {onDisk:true}; 11 | db = new Db("testing", dbops); 12 | 13 | print("Handle for: ", db); 14 | 15 | var store = db.createDocStore("docStore", {onDisk:true}); 16 | 17 | print("Handle for: ", store); 18 | 19 | var PrimaryIdx = store.createIndex("PrimaryIdx", {onDisk:true}, {b:"fwd:int"}); 20 | var SecondIdx = store.createIndex("SecondIdx", {onDisk:true}, {a:"fwd:dbl"}); 21 | var ThirdIdx = store.createIndex("ThirdIdx", {onDisk:true}, {x:"fwd:string"}); 22 | var FourthIdx = store.createIndex("FourthIdx", {onDisk:true}, {"c.d":"fwd:string"}); 23 | var FifthIdx = store.createIndex("FifthIdx", {onDisk:true}, {"yy":"fwd:int"}); 24 | 25 | print("\nstoring documents: ",{a:1.0, b:2, c: {d:"B", e:"F"}, x:"alpha0"}); 26 | 27 | doc = store.insert({a:1.0, b:3, c: {d:"A", e:"F"}, x:"alpha3"}); 28 | print("recordId for insert of a:1.0, b:2, c.d:A x:alpha3: ", doc.docId); 29 | 30 | doc = store.insert({a:1.2, b:1, c: {d:"Z", e:"F"}, x:"alpha9"}); 31 | print("recordId for insert of a:1.2, b:3, c.d:Z x:alpha9: ", doc.docId); 32 | 33 | doc = store.insert({a:1.1, b:2, c: {d:"M", e:"F"}, x:"alpha0"}); 34 | print("recordId for insert of a:1.1, b:1, c.d:M x:alpha0: ", doc.docId); 35 | 36 | var cursor1 = PrimaryIdx.createCursor(); 37 | 38 | print("\ndocuments forward sorted by field b"); 39 | cursor1.move(CursorOp.opLeft); 40 | 41 | while (doc = cursor1.move(CursorOp.opNext)) 42 | print (doc.docId, "\t", doc); 43 | 44 | print("\ndocuments reverse sorted by field b"); 45 | 46 | cursor1.move(CursorOp.opRight); 47 | 48 | while (doc = cursor1.move(CursorOp.opPrev)) 49 | print (doc.docId, "\t", doc); 50 | 51 | // re-run from left to right 52 | 53 | print("\ndocuments updated with field yy"); 54 | 55 | var id = 1; 56 | 57 | while (doc = cursor1.move(CursorOp.opNext)) { 58 | doc.yy = 2 * id++; 59 | print("update: ", doc.docId, "\t", doc.update()); 60 | } 61 | 62 | var cursor2 = FifthIdx.createCursor({cursorDeDup:true}); 63 | 64 | print ("\nfwd list on field yy of updated yy integer field:"); 65 | 66 | var nxt; 67 | 68 | while(nxt = cursor2.move(CursorOp.opNext)) 69 | print(doc = nxt); 70 | 71 | cursor2.reset(); 72 | 73 | print ("\nrev list on field yy of updated yy integer field:"); 74 | 75 | cursor2.move(CursorOp.opRight); 76 | 77 | while(nxt = cursor2.move(CursorOp.opPrev)) 78 | print(doc = nxt); 79 | 80 | print ("\nstress test 1000000 updates of the doc.yy integer field key"); 81 | var start = Date(); 82 | 83 | id = 0; 84 | 85 | while (id < 1000000) { 86 | doc.yy = 4 * id++; 87 | doc.update(); 88 | } 89 | 90 | print("elapsed time: ", (Date() - start)/1000., " seconds"); 91 | 92 | print ("\nfwd list on field yy of updated yy integer field:"); 93 | 94 | cursor2.reset(); 95 | 96 | while(nxt = cursor2.move(CursorOp.opNext)) 97 | print(doc = nxt); 98 | 99 | print ("\nstress test 1000000 updates of the doc.c.e integer field non-key"); 100 | start = Date(); 101 | 102 | id = 0; 103 | 104 | while (id < 1000000) { 105 | doc.c.e = 5 * id++; 106 | doc.update(); 107 | } 108 | 109 | print("elapsed time: ", (Date() - start)/1000., " seconds"); 110 | 111 | print ("\nfwd list on field yy integer field:"); 112 | 113 | cursor2.reset(); 114 | 115 | while(doc = cursor2.move(CursorOp.opNext)) 116 | print(doc); 117 | 118 | -------------------------------------------------------------------------------- /oldjsdb/jsdb_dbbtreeinsert.c: -------------------------------------------------------------------------------- 1 | #include "jsdb.h" 2 | #include "jsdb_db.h" 3 | 4 | Status btreeInsertSlot (DbMap *index, BtreeSet *set, uint8_t *key, uint32_t keyLen, BtreeSlotType type); 5 | 6 | Status btreeInsertKey(DbMap *index, uint8_t *key, uint32_t keyLen, uint8_t lvl, BtreeSlotType type) { 7 | uint32_t totKeyLen = keyLen; 8 | BtreeSet set[1]; 9 | Status stat; 10 | 11 | if (keyLen < 128) 12 | totKeyLen += 1; 13 | else 14 | totKeyLen += 2; 15 | 16 | while (true) { 17 | if ((stat = btreeLoadPage(index, set, key, keyLen, lvl, Btree_lockWrite, false))) 18 | return stat; 19 | 20 | if ((stat = btreeCleanPage(index, set, totKeyLen))) { 21 | if (stat == BTREE_needssplit) { 22 | if ((stat = btreeSplitPage(index, set))) 23 | return stat; 24 | else 25 | continue; 26 | } else 27 | return stat; 28 | } 29 | 30 | // add the key to the page 31 | 32 | return btreeInsertSlot (index, set, key, keyLen, type); 33 | } 34 | 35 | return OK; 36 | } 37 | 38 | // update page's fence key in its parent 39 | 40 | Status btreeFixKey (DbMap *index, uint8_t *fenceKey, uint8_t lvl, bool stopper) { 41 | uint32_t keyLen = keylen(fenceKey); 42 | BtreeSet set[1]; 43 | BtreeSlot *slot; 44 | uint8_t *ptr; 45 | Status stat; 46 | 47 | if ((stat = btreeLoadPage(index, set, fenceKey + keypre(fenceKey), keyLen - sizeof(uint64_t), lvl, Btree_lockWrite, stopper))) 48 | return stat; 49 | 50 | slot = slotptr(set->page, set->slotIdx); 51 | ptr = keyptr(set->page, set->slotIdx); 52 | 53 | // if librarian slot 54 | 55 | if (slot->type == Btree_librarian) { 56 | slot = slotptr(set->page, ++set->slotIdx); 57 | ptr = keyptr(set->page, set->slotIdx); 58 | } 59 | 60 | // update child pointer value 61 | 62 | memcpy(ptr + keypre(ptr) + keylen(ptr) - sizeof(uint64_t), fenceKey + keypre(fenceKey) + keylen(fenceKey) - sizeof(uint64_t), sizeof(uint64_t)); 63 | 64 | // release write lock 65 | 66 | btreeUnlockPage (set->latch, Btree_lockWrite); 67 | return btreeUnpinLatch(index, set->latch); 68 | } 69 | 70 | // install new key onto page 71 | // page must already be checked for 72 | // adequate space 73 | 74 | Status btreeInsertSlot (DbMap *index, BtreeSet *set, uint8_t *key, uint32_t keyLen, BtreeSlotType type) { 75 | uint32_t idx, prefixLen; 76 | BtreeSlot *slot; 77 | uint8_t *ptr; 78 | 79 | // if found slot > desired slot and previous slot 80 | // is a librarian slot, use it 81 | 82 | if( set->slotIdx > 1 ) 83 | if( slotptr(set->page, set->slotIdx-1)->type == Btree_librarian ) 84 | set->slotIdx--; 85 | 86 | // calculate key length 87 | 88 | prefixLen = keyLen < 128 ? 1 : 2; 89 | 90 | // copy key onto page 91 | 92 | set->page->min -= prefixLen + keyLen; 93 | ptr = keyaddr(set->page, set->page->min); 94 | 95 | if( keyLen < 128 ) 96 | *ptr++ = keyLen; 97 | else 98 | *ptr++ = keyLen/256 | 0x80, *ptr++ = keyLen; 99 | 100 | memcpy (ptr, key, keyLen); 101 | slot = slotptr(set->page, set->slotIdx); 102 | 103 | // find first empty slot 104 | 105 | for( idx = set->slotIdx; idx < set->page->cnt; slot++, idx++ ) 106 | if( slot->dead ) 107 | break; 108 | 109 | if( idx == set->page->cnt ) 110 | idx++, set->page->cnt++, slot++; 111 | 112 | set->page->act++; 113 | 114 | while( idx-- > set->slotIdx ) 115 | slot->bits = slot[-1].bits, slot--; 116 | 117 | // fill in new slot 118 | 119 | slot->bits = set->page->min; 120 | slot->type = type; 121 | 122 | btreeUnlockPage (set->latch, Btree_lockWrite); 123 | return btreeUnpinLatch(index, set->latch); 124 | } 125 | 126 | -------------------------------------------------------------------------------- /jsscripts/test_str.js: -------------------------------------------------------------------------------- 1 | print("\n\nbegin test_str.js"); 2 | print("------------------"); 3 | 4 | var plainText = "ROMEO: \"But, soft! what light through yonder window breaks?\n\ 5 | It is the east, and Juliet is the sun.\n\ 6 | Arise, fair sun, and kill the envious moon,\n\ 7 | Who is already sick and pale with grief,\n\ 8 | That thou her maid art far more fair than she:\n\ 9 | Be not her maid, since she is envious;\n\ 10 | Her vestal livery is but sick and green\n\ 11 | And none but fools do wear it; cast it off.\n\ 12 | It is my lady, O, it is my love!\n\ 13 | O, that she knew she were!\n\ 14 | She speaks yet she says nothing: what of that?\n\ 15 | Her eye discourses; I will answer it.\n\ 16 | I am too bold, \'tis not to me she speaks:\n\ 17 | Two of the fairest stars in all the heaven,\n\ 18 | Having some business, do entreat her eyes\n\ 19 | To twinkle in their spheres till they return.\n\ 20 | What if her eyes were there, they in her head?\n\ 21 | The brightness of her cheek would shame those stars,\n\ 22 | As daylight doth a lamp; her eyes in heaven\n\ 23 | Would through the airy region stream so bright\n\ 24 | That birds would sing and think it were not night.\n\ 25 | See, how she leans her cheek upon her hand!\n\ 26 | O, that I were a glove upon that hand,\n\ 27 | That I might touch that cheek!\n\ 28 | JULIET: Ay me!\n\ 29 | ROMEO: She speaks:\n\ 30 | O, speak again, bright angel! for thou art\n\ 31 | As glorious to this night, being o\'er my head\n\ 32 | As is a winged messenger of heaven\n\ 33 | Unto the white-upturned wondering eyes\n\ 34 | Of mortals that fall back to gaze on him\n\ 35 | When he bestrides the lazy-pacing clouds\n\ 36 | And sails upon the bosom of the air."; 37 | 38 | function ChunkStr(str, size) { 39 | var n = Math.ceil(str.length / size); 40 | var chunks = new Array(n); 41 | 42 | for (var i = 0; i < n; i++) 43 | chunks[i] = str.substr(i * size, size); 44 | 45 | return chunks; 46 | } 47 | 48 | var array = ["aaaaaaaaaaaaaaaa", "bbbbbbbbbbbbbbbb", "cccccccccccccccc", 4]; 49 | 50 | print ('\nmake array["aaaaaaaaaaaaaaaa", "bbbbbbbbbbbbbbbb", "cccccccccccccccc", 4]: ', array); 51 | print("array[0].charCodeAt(6): ", array[0].charCodeAt(6)); 52 | print("Expecting typeof array[0]: ", typeof array[0]); 53 | 54 | print("\narray.join w/'->': ", array.join("->")); 55 | print("\nmake 16 byte chunks\n"); 56 | var x = ChunkStr(plainText, 16); 57 | print(x); 58 | 59 | print("\nrejoin 16 byte chunks\n"); 60 | print(x.join("")); 61 | 62 | print("\nmake more 16 byte chunks\n"); 63 | print(ChunkStr("1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef", 16)); 64 | 65 | var test = new String(5); 66 | print("\nmake new String(5):", test); 67 | 68 | var testing = { count : 5 }; 69 | print("\nmake testing object ", testing, " w/count: ", testing.count); 70 | 71 | array = Array(4); 72 | print ("\nmake Array(4): ", array); 73 | 74 | var item = {item:"abc"}; 75 | print("make item: ", item); 76 | 77 | array.test = item; 78 | print("\nadd item to array: ", array.test); 79 | 80 | var test = String(testing.count); 81 | 82 | print("\n make new string: ", test); 83 | 84 | while (test.length < 3) test = "0" + test; 85 | 86 | print("\nextend test to 3 chars: ", test); 87 | 88 | var str = " "; 89 | var sav = str; 90 | 91 | for(var i = 0; i < 1024 * 1024; i++) 92 | str += " "; 93 | 94 | print("original 1 byte string: ", sav.length); 95 | print("\n make 1M char string: ", str.length); 96 | 97 | 98 | function foo(x) { 99 | return x.a; 100 | } 101 | print( "\n\nExpecting: {\"x\":10,\"y\":20} - ", foo({a:{x:10,y:20},b:7}) ); 102 | 103 | -------------------------------------------------------------------------------- /oldjsdb/jsdb_dbarena.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifdef _WIN32 4 | #define WIN32_LEAN_AND_MEAN 5 | #include 6 | #endif 7 | 8 | #include "jsdb_dbpq.h" 9 | 10 | #define MAX_segs 1000 11 | #define MIN_segsize 131072 12 | 13 | #define MAX_path 4096 14 | #define MAX_blk 24 // max arena blk size in bits 15 | 16 | // name ID LIFO list 17 | 18 | typedef struct { 19 | DbAddr next; // next entry in ID LIFO list 20 | uint64_t id; // entry auto-incrementing ID 21 | uint64_t ref; // entry delete reference (0 == add) 22 | uint32_t len; // length of name 23 | uint8_t name[0];// name characters 24 | } IdEntry; 25 | 26 | // on disk arena segment 27 | 28 | typedef struct { 29 | uint64_t off; // file offset of the segment 30 | uint64_t size; // size of the segment 31 | DocId nextDoc; // highest document ID in use 32 | } DbSeg; 33 | 34 | // on disk/mmap arena seg zero 35 | 36 | typedef struct { 37 | DbSeg segs[MAX_segs]; // segment meta-data 38 | DbAddr freeBlk[MAX_blk];// Arena free block frames 39 | DbAddr freeFrame[1]; // next free frame address 40 | DbAddr nextObject; // next Object address 41 | DbAddr childIdRoot; // child Id LIFO list, no read lock 42 | uint64_t childId; // highest child ID issued 43 | uint32_t idSize; // size of the Id array element 44 | uint8_t currSeg; // index of highest segment 45 | char mutex; // object allocation lock 46 | char type; // arena hndl type 47 | char drop; // arena dropped 48 | } DbArena; 49 | 50 | // in memory children object 51 | 52 | typedef struct { 53 | uint64_t childId; // child id 54 | DbMap *child; // loaded map 55 | } DbChild; 56 | 57 | // handle value types 58 | 59 | typedef enum { 60 | Hndl_newarena = 0, 61 | Hndl_database, 62 | Hndl_docStore, 63 | Hndl_btreeIndex, 64 | Hndl_artIndex, 65 | Hndl_colIndex, 66 | Hndl_iterator, 67 | Hndl_btreeCursor, 68 | Hndl_artCursor, 69 | Hndl_docVersion 70 | } HandleSubType; 71 | 72 | // user's arena handle 73 | 74 | typedef struct { 75 | RWLock latch[1]; // handle use counter 76 | uint64_t id; // child ID in parent 77 | DbMap *map; // arena -- NULL if dropped 78 | void *next; // next handle for arena 79 | } Handle; 80 | 81 | // in memory arena map 82 | 83 | struct DbMap_ { 84 | char *base[MAX_segs]; // pointers to mapped segment memory 85 | value_t children[1]; // object containing child handles 86 | uint64_t childId; // highest child id in children 87 | #ifndef _WIN32 88 | int hndl[1]; // OS file handle 89 | #else 90 | HANDLE hndl[MAX_segs]; 91 | HANDLE maphndl[MAX_segs]; 92 | #endif 93 | DbMap *parent, *db; // parent and database map 94 | IdEntry *myEntry; // pointer to IdEntry in parent 95 | uint32_t cpuCount; // number of CPUS 96 | uint32_t maxSeg; // maximum segment array index in use 97 | DbArena *arena; // ptr to mapped seg zero 98 | char created; // new arena file created 99 | char onDisk; // on disk bool flag 100 | char mutex; // mapping lock 101 | }; 102 | 103 | // the database arena 104 | 105 | typedef struct { 106 | DbPQ pq[1]; // timestamp priority queue 107 | uint32_t verCnt; // version for handle names 108 | uint32_t maxVer; // maximum version table idx 109 | DbAddr freePQ[MAX_set]; // available priority queue entries 110 | DbAddr freeTxn[MAX_set][Txn_max]; 111 | } DataBase; 112 | 113 | #define database(db) ((DataBase *)(db->arena + 1)) 114 | 115 | DbMap *createMap(IdEntry *entry, DbMap *parent, uint32_t baseSize, uint64_t initSize, bool onDisk); 116 | void returnFreeFrame(DbMap *map, DbAddr slot); 117 | uint64_t allocBlk (DbMap *map, uint32_t size); 118 | -------------------------------------------------------------------------------- /js_dbver.c: -------------------------------------------------------------------------------- 1 | #include "js.h" 2 | #include "js_db.h" 3 | #include "js_dbindex.h" 4 | 5 | #include 6 | 7 | // insert a document or an updated version into a docStore 8 | // returns prev document addr from the slot 9 | 10 | JsStatus writeRawDoc(Handle *docHndl, value_t val, ObjId *docId) { 11 | DbMap *map = MapAddr(docHndl); 12 | uint32_t docSize, rawSize, baseOff; 13 | DbAddr newAddr, prevAddr; 14 | document_t *rawDoc; 15 | JsDoc *jsDoc; // follows document 16 | DbAddr *docSlot; 17 | value_t s; 18 | 19 | s.bits = vt_status; 20 | 21 | docSize = calcSize(val, true); 22 | docSlot = fetchIdSlot(map, *docId); 23 | prevAddr = *docSlot; 24 | 25 | DocIdXtra(docId)->txnAccess = TxnRaw; 26 | 27 | rawSize = docSize + sizeof(JsDoc) + sizeof(struct Document); 28 | 29 | // allocate space in docStore for the document 30 | 31 | if ((newAddr.bits = allocDocStore(docHndl, rawSize, false))) 32 | rawSize = db_rawSize(newAddr); 33 | else 34 | return (JsStatus)ERROR_outofmemory; 35 | 36 | // set up the document header 37 | 38 | rawDoc = getObj(map, newAddr); 39 | memset(rawDoc, 0, sizeof(struct Document)); 40 | 41 | rawDoc->ourAddr.bits = newAddr.bits; 42 | rawDoc->docId.bits = docId->bits; 43 | rawDoc->docType = VerRaw; 44 | 45 | jsDoc = (JsDoc *)(rawDoc + 1); 46 | jsDoc->maxOffset = rawSize; 47 | 48 | baseOff = sizeof(struct Document) + sizeof(JsDoc); 49 | 50 | // marshal directly into the mmap file 51 | 52 | marshalDoc(val, rawDoc->base, baseOff, docSize, jsDoc->value, true); 53 | 54 | // install the document in the slot 55 | // and return old addr 56 | 57 | docSlot->bits = newAddr.bits; 58 | return (JsStatus)prevAddr.bits; 59 | } 60 | 61 | // write/update mvcc doc 62 | 63 | JsStatus writeMVCCDoc(Handle *docHndl, value_t val, ObjId *docId) { 64 | DbMap *map = MapAddr(docHndl); 65 | uint32_t docSize, baseOff; 66 | MVCCResult result; 67 | DbAddr *docSlot; 68 | JsDoc *jsDoc; 69 | value_t s; 70 | Doc *doc; // follows Document 71 | Ver *ver; 72 | 73 | s.bits = vt_status; 74 | 75 | docSize = calcSize(val, true); 76 | docSlot = fetchIdSlot(map, *docId); 77 | 78 | result = mvcc_installNewDocVer(docHndl, sizeof(JsDoc) + docSize, docId); 79 | doc = result.object; 80 | ver = (Ver *)(doc->doc->base + doc->newestVer); 81 | jsDoc = (JsDoc *)(ver + 1); 82 | baseOff = doc->newestVer - sizeof(Ver) - sizeof(JsDoc) - docSize; 83 | 84 | // marshal directly into the mmap file 85 | 86 | marshalDoc(val, doc->doc->base, baseOff, docSize, jsDoc->value, true); 87 | return (JsStatus)DB_OK; 88 | } 89 | 90 | JsStatus writeDoc(Handle *docHndl, value_t val, ObjId *docId) { 91 | struct Document *prevDoc; 92 | DocStore *docStore; 93 | JsStatus stat = (JsStatus)DB_OK; 94 | DbMap *docMap; 95 | 96 | docMap = MapAddr(docHndl); 97 | docStore = (DocStore *)(docMap->arena + 1); 98 | 99 | if(docId->bits == 0) 100 | docId->bits = allocObjId(docMap, listFree(docHndl, 0), listWait(docHndl, 0)); 101 | 102 | switch (docStore->docType) { 103 | case VerRaw: 104 | DocIdXtra(docId)->txnAccess = TxnRaw; 105 | prevDoc = writeRawDoc(docHndl, val, docId); 106 | 107 | if (jsError(prevDoc)) 108 | stat = (JsStatus)prevDoc; 109 | 110 | break; 111 | 112 | case VerMvcc: 113 | DocIdXtra(docId)->txnAccess = TxnWrt; 114 | prevDoc = writeMVCCDoc(docHndl, val, docId); 115 | 116 | if (jsError(prevDoc)) 117 | stat = (JsStatus)prevDoc; 118 | 119 | break; 120 | } 121 | 122 | return stat; 123 | } 124 | -------------------------------------------------------------------------------- /data/stack.hh: -------------------------------------------------------------------------------- 1 | # C++ skeleton for Bison 2 | 3 | # Copyright (C) 2002-2013 Free Software Foundation, Inc. 4 | 5 | # This program is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program. If not, see . 17 | 18 | m4_pushdef([b4_copyright_years], 19 | [2002-2013]) 20 | 21 | # b4_stack_define 22 | # --------------- 23 | m4_define([b4_stack_define], 24 | [[ template > 25 | class stack 26 | { 27 | public: 28 | // Hide our reversed order. 29 | typedef typename S::reverse_iterator iterator; 30 | typedef typename S::const_reverse_iterator const_iterator; 31 | 32 | stack () 33 | : seq_ () 34 | { 35 | } 36 | 37 | stack (unsigned int n) 38 | : seq_ (n) 39 | { 40 | } 41 | 42 | inline 43 | T& 44 | operator[] (unsigned int i) 45 | { 46 | return seq_[seq_.size () - 1 - i]; 47 | } 48 | 49 | inline 50 | const T& 51 | operator[] (unsigned int i) const 52 | { 53 | return seq_[seq_.size () - 1 - i]; 54 | } 55 | 56 | /// Steal the contents of \a t. 57 | /// 58 | /// Close to move-semantics. 59 | inline 60 | void 61 | push (T& t) 62 | { 63 | seq_.push_back (T()); 64 | operator[](0).move (t); 65 | } 66 | 67 | inline 68 | void 69 | pop (unsigned int n = 1) 70 | { 71 | for (; n; --n) 72 | seq_.pop_back (); 73 | } 74 | 75 | void 76 | clear () 77 | { 78 | seq_.clear (); 79 | } 80 | 81 | inline 82 | typename S::size_type 83 | size () const 84 | { 85 | return seq_.size (); 86 | } 87 | 88 | inline 89 | const_iterator 90 | begin () const 91 | { 92 | return seq_.rbegin (); 93 | } 94 | 95 | inline 96 | const_iterator 97 | end () const 98 | { 99 | return seq_.rend (); 100 | } 101 | 102 | private: 103 | stack (const stack&); 104 | stack& operator= (const stack&); 105 | /// The wrapped container. 106 | S seq_; 107 | }; 108 | 109 | /// Present a slice of the top of a stack. 110 | template > 111 | class slice 112 | { 113 | public: 114 | slice (const S& stack, unsigned int range) 115 | : stack_ (stack) 116 | , range_ (range) 117 | { 118 | } 119 | 120 | inline 121 | const T& 122 | operator [] (unsigned int i) const 123 | { 124 | return stack_[range_ - i]; 125 | } 126 | 127 | private: 128 | const S& stack_; 129 | unsigned int range_; 130 | }; 131 | ]]) 132 | 133 | b4_defines_if( 134 | [b4_output_begin([b4_dir_prefix[]stack.hh]) 135 | b4_copyright([Stack handling for Bison parsers in C++])[ 136 | 137 | /** 138 | ** \file ]b4_dir_prefix[stack.hh 139 | ** Define the ]b4_namespace_ref[::stack class. 140 | */ 141 | 142 | ]b4_cpp_guard_open([b4_dir_prefix[]stack.hh])[ 143 | 144 | # include 145 | 146 | ]b4_namespace_open[ 147 | ]b4_stack_define[ 148 | ]b4_namespace_close[ 149 | 150 | ]b4_cpp_guard_close([b4_dir_prefix[]stack.hh]) 151 | b4_output_end() 152 | ]) 153 | 154 | m4_popdef([b4_copyright_years]) 155 | -------------------------------------------------------------------------------- /oldjsdb/jsdb_dbbtreelatch.c: -------------------------------------------------------------------------------- 1 | #include "jsdb.h" 2 | #include "jsdb_db.h" 3 | 4 | // place write, read, or parent lock on requested page_no. 5 | 6 | void btreeLockPage(BtreeLatch *latch, BtreeLock mode) { 7 | switch( mode ) { 8 | case Btree_lockRead: 9 | readLock (latch->readwr); 10 | break; 11 | case Btree_lockWrite: 12 | writeLock (latch->readwr); 13 | break; 14 | case Btree_lockAccess: 15 | readLock (latch->access); 16 | break; 17 | case Btree_lockDelete: 18 | writeLock (latch->access); 19 | break; 20 | case Btree_lockParent: 21 | writeLock (latch->parent); 22 | break; 23 | case Btree_lockLink: 24 | writeLock (latch->link); 25 | break; 26 | } 27 | } 28 | 29 | void btreeUnlockPage(BtreeLatch *latch, BtreeLock mode) 30 | { 31 | switch( mode ) { 32 | case Btree_lockWrite: 33 | rwUnlock (latch->readwr); 34 | break; 35 | case Btree_lockRead: 36 | rwUnlock (latch->readwr); 37 | break; 38 | case Btree_lockAccess: 39 | rwUnlock (latch->access); 40 | break; 41 | case Btree_lockDelete: 42 | rwUnlock (latch->access); 43 | break; 44 | case Btree_lockParent: 45 | rwUnlock (latch->parent); 46 | break; 47 | case Btree_lockLink: 48 | rwUnlock (latch->link); 49 | break; 50 | } 51 | } 52 | 53 | // Assign and pin latch table entry 54 | 55 | BtreeLatch *btreePinLatch (DbMap *index, DbAddr pageNo) { 56 | int hashIdx = pageNo.bits % Btree_hashsize; 57 | BtreeIndex *btree = btreeIndex(index); 58 | BtreeLatch *latch; 59 | DbAddr addr; 60 | 61 | if (pageNo.addr == btree->root.addr) 62 | return btree->rootLatch; 63 | 64 | lockLatch(btree->hashTable[hashIdx].latch); 65 | 66 | if ((addr.bits = btree->hashTable[hashIdx].addr)) do { 67 | latch = getObj(index, addr); 68 | if (latch->pageNo.bits == pageNo.bits) { 69 | latch->pinCnt++; 70 | unlockLatch(btree->hashTable[hashIdx].latch); 71 | return latch; 72 | } 73 | } while ((addr.bits = latch->next.bits)); 74 | 75 | // our page isn't in the hash table, 76 | // make a new entry 77 | 78 | if ((addr.bits = allocObj(index, &btree->freePages[Btree_latchSet], Btree_latchSet, sizeof(BtreeLatch), true) )) 79 | latch = getObj(index, addr); 80 | else 81 | return NULL; 82 | 83 | latch->next.bits = btree->hashTable[hashIdx].addr; 84 | latch->pageNo.bits = pageNo.bits; 85 | latch->addr.bits = addr.bits; 86 | latch->pinCnt = 1; 87 | 88 | // place latch into hashtable, removing lock 89 | 90 | btree->hashTable[hashIdx].bits = addr.bits; 91 | return latch; 92 | } 93 | 94 | // unpin latch set and remove if zero 95 | 96 | Status btreeUnpinLatch (DbMap *index, BtreeLatch *latch) { 97 | int hashIdx = latch->pageNo.bits % Btree_hashsize; 98 | BtreeIndex *btree = btreeIndex(index); 99 | BtreeLatch *prevEntry, *nextEntry; 100 | DbAddr addr; 101 | 102 | if (latch->pageNo.addr == btree->root.addr) 103 | return OK; 104 | 105 | lockLatch(btree->hashTable[hashIdx].latch); 106 | 107 | if (--latch->pinCnt) { 108 | unlockLatch(btree->hashTable[hashIdx].latch); 109 | return OK; 110 | } 111 | 112 | prevEntry = NULL; 113 | 114 | if ((addr.bits = btree->hashTable[hashIdx].addr)) do { 115 | nextEntry = getObj(index, addr); 116 | if (nextEntry == latch) { 117 | if (prevEntry) 118 | prevEntry->next.bits = latch->next.bits; 119 | else 120 | btree->hashTable[hashIdx].bits = latch->next.bits; 121 | 122 | unlockLatch(btree->hashTable[hashIdx].latch); 123 | 124 | if (addSlotToFrame(index, &btree->freePages[Btree_latchSet], addr.bits)) 125 | return OK; 126 | return ERROR_outofmemory; 127 | } 128 | prevEntry = nextEntry; 129 | } while ((addr.bits = nextEntry->next.bits)); 130 | 131 | // latch not found error 132 | 133 | return ERROR_btreepagelatchnotfound; 134 | } 135 | -------------------------------------------------------------------------------- /js_dbiterator.c: -------------------------------------------------------------------------------- 1 | #include "js.h" 2 | #include "js_props.h" 3 | #include "js_vector.h" 4 | 5 | #include "js_db.h" 6 | #include "js_dbindex.h" 7 | 8 | value_t fcnIterNext(value_t *args, value_t thisVal, environment_t *env) { 9 | Handle *docHndl; 10 | DbMap *docMap; 11 | uint32_t count, idx = 0; 12 | Iterator *it; 13 | value_t s, v; 14 | 15 | s.bits = vt_status; 16 | 17 | if((docHndl = js_handle(thisVal, Hndl_iterator))) 18 | it = ClntAddr(docHndl); 19 | else 20 | return s.status = DB_ERROR_handleclosed, s; 21 | 22 | docMap = MapAddr(docHndl); 23 | 24 | if (vec_cnt(args)) 25 | count = (uint32_t)args[0].nval; 26 | else 27 | count = 0; 28 | 29 | while (iteratorNext(docHndl)) { 30 | value_t d; 31 | 32 | d.bits = vt_docId; 33 | d.idBits = it->docId.bits; 34 | d.hndlIdx = docHndl->hndlIdx; 35 | 36 | if (count == 0) { 37 | v = d; 38 | idx++; 39 | break; 40 | } 41 | 42 | if (idx == 0) 43 | v = newArray(array_value, count); 44 | 45 | vec_push(v.aval->valuePtr, d); 46 | if (++idx > count) break; 47 | } 48 | 49 | releaseHandle(docHndl); 50 | 51 | if (idx) return v; 52 | 53 | return s.status = DB_ITERATOR_eof, s; 54 | } 55 | 56 | value_t fcnIterPrev(value_t *args, value_t thisVal, environment_t *env) { 57 | int count, idx = 0; 58 | Handle *docHndl; 59 | Iterator *it; 60 | value_t s, v; 61 | DbMap *docMap; 62 | s.bits = vt_status; 63 | 64 | if((docHndl = js_handle(thisVal, Hndl_iterator))) 65 | it = ClntAddr(docHndl); 66 | else 67 | return s.status = DB_ERROR_handleclosed, s; 68 | 69 | docMap = MapAddr(docHndl); 70 | 71 | if (vec_cnt(args)) 72 | count = (uint32_t)args[0].nval; 73 | else 74 | count = 0; 75 | 76 | while (iteratorPrev(docHndl)) { 77 | value_t d; 78 | 79 | d.bits = vt_docId; 80 | d.idBits = it->docId.bits; 81 | d.hndlIdx = docHndl->hndlIdx; 82 | 83 | if (count == 0) { 84 | v = d; 85 | idx++; 86 | break; 87 | } 88 | 89 | if (idx == 0) v = newArray(array_value, count); 90 | 91 | vec_push(v.aval->valuePtr, d); 92 | if (++idx > count) break; 93 | } 94 | 95 | releaseHandle(docHndl); 96 | 97 | if (idx) return v; 98 | 99 | return s.status = DB_ITERATOR_eof, s; 100 | } 101 | 102 | // iterator.seek(ver) 103 | 104 | value_t fcnIterSeek(value_t *args, value_t thisVal, environment_t *env) { 105 | IteratorOp op = IterSeek; 106 | Handle *docHndl; 107 | Iterator *it; 108 | ObjId docId; 109 | value_t s; 110 | DbMap *map; 111 | 112 | s.bits = vt_status; 113 | s.status = OK; 114 | 115 | if (args->type == vt_int) { 116 | docId.bits = 0; 117 | op = (IteratorOp)args->nval; 118 | } else if (args->type == vt_docId) { 119 | docId.bits = args->idBits; 120 | op = IterSeek; 121 | } else 122 | return s.status = ERROR_not_operator_int, s; 123 | 124 | if((docHndl = js_handle(thisVal, Hndl_iterator))) 125 | it = ClntAddr(docHndl); 126 | else 127 | return s.status = DB_ERROR_handleclosed, s; 128 | 129 | map = MapAddr(docHndl); 130 | 131 | if ((iteratorSeek(docHndl, op, docId))) { 132 | value_t d; 133 | d.bits = vt_docId; 134 | d.idBits = it->docId.bits; 135 | d.hndlIdx = docHndl->hndlIdx; 136 | } else 137 | s.status = DB_ITERATOR_eof; 138 | 139 | releaseHandle(docHndl); 140 | return s; 141 | } 142 | 143 | PropFcn builtinIterFcns[] = { 144 | { fcnIterNext, "next" }, 145 | { fcnIterPrev, "prev" }, 146 | { fcnIterSeek, "seek" }, 147 | { NULL, NULL} 148 | }; 149 | 150 | PropVal builtinIterProp[] = { 151 | // { propIterOnDisk, "onDisk" }, 152 | { NULL, NULL} 153 | }; 154 | 155 | -------------------------------------------------------------------------------- /data/xslt/bison.xsl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 23 | 24 | 27 | 28 | 33 | 38 | 43 | 49 | 55 | 56 | 57 | 58 | 59 | 60 | 67 | 68 | 69 | 70 | 71 | 75 | 79 | 80 | s 81 | 82 | 83 | r 84 | 85 | 86 | 87 | 88 | 89 | , 90 | 91 | 92 | 93 | 94 | 0 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | -------------------------------------------------------------------------------- /oldjsdb/jsdb_dbcol.h: -------------------------------------------------------------------------------- 1 | // btree control structure 2 | 3 | #define BT_blk (1 << BT_bits) 4 | #define BT_bits 14 5 | #define BT_lvl 6 // maximum level of index blocks 6 | 7 | #define BT_stopper 16 // length of stopper key 8 | 9 | typedef enum { 10 | BTREE_ok = 0, 11 | BTREE_struct, 12 | BTREE_intr, 13 | BTREE_eof, 14 | BTREE_write, 15 | BTREE_hdr, // header crc error 16 | BTREE_blk0, 17 | BTREE_log, // short log read 18 | BTREE_ext, 19 | BTREE_zero, // can't write zero length record 20 | BTREE_crc, // index body crc error 21 | BTREE_map, // unable to map block 22 | BTREE_stop, // stopper key deleted 23 | BTREE_lvl, // too many levels > BT_lvl 24 | BTREE_none, // no key found 25 | BTREE_chg, // update with different keys 26 | BTREE_cache, // cache consistency error 27 | BTREE_max // maximum offset testing 28 | } BT_resp; 29 | 30 | typedef struct { 31 | DbAddr rowid; // last database row-id 32 | uchar resv[28]; // reserved for expansion 33 | } BT_zero; 34 | 35 | typedef struct { 36 | BT_hdr hdr[1]; // standard msg header 37 | uchar cnt[2]; // count of keys for record 38 | uchar off[2]; // next available key offset 39 | uchar amt[2]; // avail bytes in key area 40 | DbAddr rowid; // row-id of record 41 | DbAddr chain; // record chain 42 | } BT_rec; 43 | 44 | typedef struct { 45 | uint flush:1; // record file flush 46 | uint lock:1; // record offset locked 47 | 48 | BT_resp err; // last error code 49 | 50 | uchar *map; // address of page mapping 51 | off_t page; // offset of page mapping 52 | uint xtent; // extent of page mapping 53 | 54 | off_t off; // offset of record 55 | off_t next; // next offset for scan 56 | BT_rec *rec; // mapped data record 57 | int len; // length of record 58 | int log; // fd of record file 59 | 60 | off_t chain; // current chain offset 61 | off_t prev; // previous chain offset 62 | 63 | int idx; // DataBase index file 64 | int lvl; // DataBase B-Tree depth 65 | int mode; // DataBase open mode 66 | int size; // DataBase idx block 67 | 68 | BT_rec *empty; // DataBase empty block for splits 69 | BT_zero *zero; // DataBase block zero extra data 70 | Datum name[1]; // DataBase name 71 | 72 | int cnt[BT_lvl]; // B-tree level key count 73 | int slot[BT_lvl]; // B-tree level slot index 74 | off_t addr[BT_lvl]; // B-tree index blk offset 75 | uchar *key[BT_lvl]; // B-tree key found 76 | BT_rec *array[BT_lvl]; // B-tree level memory address 77 | 78 | ushort base[BT_cache]; // B-tree cache base block 79 | void *virt[BT_cache]; // B-tree cache virtual addr 80 | ushort lru[BT_cache]; // B-tree cache next lru 81 | uint cache; // B-tree cache starter cnt 82 | } *Btree; 83 | 84 | typedef struct BtPage_ { 85 | uint cnt; // count of keys in page 86 | uint act; // count of active keys 87 | uint min; // next key/value offset 88 | uint fence; // page fence key offset 89 | uint garbage; // page garbage in bytes 90 | unsigned char lvl; // level of page, zero = leaf 91 | unsigned char free; // page is on the free chain 92 | unsigned char kill; // page is being deleted 93 | unsigned char nopromote; // page is being constructed 94 | DbAddr right, left; // page numbers to right and left 95 | } *BtPage; 96 | 97 | BT_resp bt_retrieve (Btree, uchar *, uint size); 98 | BT_resp bt_replace (Btree, BT_rec *, uint size, int flag); 99 | BT_resp bt_update (Btree bt, BT_rec *rec, uint len); 100 | BT_resp bt_insert (Btree, uchar *key, off_t off); 101 | BT_resp bt_chain (Btree, uchar *key); 102 | BT_resp bt_delete (Btree); 103 | BT_resp bt_next (Btree bt); 104 | 105 | BT_resp bt_find (Btree, uchar *key); 106 | 107 | BT_resp bt_inskey (Btree, int lvl, uchar *key); 108 | BT_resp bt_delkey (Btree, int lvl); 109 | 110 | BT_resp bt_close (Btree); 111 | BT_resp bt_open (Btree); 112 | 113 | void bt_unlock (Btree); 114 | void bt_lock (Btree); 115 | -------------------------------------------------------------------------------- /systemObj.js: -------------------------------------------------------------------------------- 1 | function Function() { 2 | return eval(arguments); 3 | }; 4 | 5 | jsdb_installProps(Function, builtins.builtinFcn, _values.vt_closure); 6 | 7 | Function.prototype.bind = function() { 8 | }; 9 | 10 | Function.prototype.toString = function() { 11 | return "Fcn " + this.name; 12 | }; 13 | 14 | function Array() { 15 | var ans = []; 16 | 17 | if(arguments.length == 1) 18 | if(typeof arguments[0] == "integer" || typeof arguments[0] == "number") { 19 | if (arguments[0]) 20 | ans[arguments[0]-1]=undefined; 21 | return ans; 22 | } 23 | 24 | for( var idx = 0; idx < arguments.length; idx++) 25 | ans[idx] = arguments[idx]; 26 | 27 | return ans; 28 | } 29 | 30 | jsdb_installProps(Array, builtins.builtinArray, _values.vt_array); 31 | 32 | Array.prototype.push = function() { 33 | var nxt = this.length; 34 | 35 | for( var idx = 0; idx < arguments.length; idx++) 36 | this[nxt++] = arguments[idx]; 37 | 38 | return nxt; 39 | }; 40 | 41 | Array.prototype.sort = function() { 42 | var array = this; 43 | 44 | if (this.length > 1) 45 | qsort (0, this.length - 1); 46 | 47 | return array; 48 | 49 | function swap (i, j) { 50 | var t = array[i]; 51 | array[i] = array[j]; 52 | array[j] = t; 53 | } 54 | 55 | function partition(left, right) { 56 | var pv = array[Math.floor((right + left) / 2)]; 57 | var j = right; 58 | var i = left; 59 | 60 | while (i <= j) { 61 | while (array[i] < pv) 62 | i++; 63 | 64 | while (array[j] > pv) 65 | j--; 66 | 67 | if (i <= j) 68 | swap (i++, j--); 69 | } 70 | 71 | return i; 72 | } 73 | 74 | function qsort(left, right) { 75 | var idx; 76 | 77 | if (left < right) { 78 | idx = partition(left, right); 79 | 80 | if (left < idx - 1) 81 | qsort(left, idx - 1); 82 | if (idx < right) 83 | qsort (idx, right); 84 | } 85 | } 86 | }; 87 | 88 | var _JSONtype = enum { 89 | JSONstringify = 1, 90 | JSONparse 91 | }; 92 | 93 | var JSON = {}; 94 | 95 | JSON.stringify = function(value) { 96 | return jsdb_json(_JSONtype.JSONstringify, value); 97 | }; 98 | 99 | JSON.parse = function(value) { 100 | return jsdb_json(_JSONtype.JSONparse, value); 101 | }; 102 | 103 | function Date() { 104 | var date = jsdb_newDate(arguments); 105 | 106 | if (!this) 107 | return date; 108 | 109 | this.setValue(date); 110 | } 111 | 112 | jsdb_installProps(Date, builtins.builtinDate, _values.vt_date); 113 | 114 | function String(v) { 115 | if (this) 116 | this.setValue(v.toString()); 117 | else 118 | return v.toString(); 119 | } 120 | 121 | jsdb_installProps(String, builtins.builtinStr, _values.vt_string); 122 | 123 | String.fromCharCode = function() { 124 | return jsdb_fromCharCode(arguments); 125 | }; 126 | 127 | function Number(n) { 128 | if (this) 129 | this.setValue(n); 130 | else 131 | return n; 132 | } 133 | 134 | jsdb_installProps(Number, builtins.builtinNum, _values.vt_int, _values.vt_dbl, _values.vt_infinite, _values.vt_null, _values.vt_nan); 135 | 136 | Number.EPSILON = 2.220446049250313E-16; 137 | Number.MAX_SAFE_INTEGER = 65536 * 65536 * 65536 * 32768; 138 | Number.MAX_VALUE = 1.7976931348623157E308; 139 | Number.MIN_SAFE_INTEGER = -65536 * 65536 * 65536 * 32768; 140 | Number.MIN_VALUE = 5E-324; 141 | Number.NaN = 0/0; 142 | Number.NEGATIVE_INFINITY = -1/0; 143 | Number.POSITIVE_INFINITY = 1/0; 144 | 145 | Number.isNaN = function(x) { return typeof x == "NaN"; }; 146 | Number.isFinite = function(x) { return typeof x == "number" || typeof x == "integer"; }; 147 | Number.isInteger = function(x) { return typeof x == "integer"; }; 148 | Number.isSafeInteger = function(x) { return true; }; 149 | Number.parseFloat = function(x) { return x + 0; }; 150 | Number.parseInt = function(x) { return x + 0; }; 151 | 152 | function Boolean() { 153 | if (arguments.length == 0) 154 | if (this) 155 | this.setValue(false); 156 | else 157 | return false; 158 | 159 | else if (arguments[0]) 160 | if (this) 161 | this.setValue(true); 162 | else 163 | return true; 164 | 165 | else if (this) 166 | this.setValue(false); 167 | else 168 | return false; 169 | } 170 | 171 | jsdb_installProps(Boolean, builtins.builtinBool, _values.vt_bool); 172 | 173 | -------------------------------------------------------------------------------- /oldjsdb/jsdb_dbcursor.c: -------------------------------------------------------------------------------- 1 | #include "jsdb.h" 2 | #include "jsdb_db.h" 3 | 4 | // construct a db cursor 5 | // given the index 6 | // and a field array 7 | 8 | value_t makeCursor(value_t val, DbMap *index, bool reverse, value_t start, value_t limit) { 9 | value_t s; 10 | 11 | switch (index->arena->type) { 12 | case Hndl_btreeIndex: 13 | return btreeCursor(val, index, reverse, start, limit); 14 | 15 | case Hndl_artIndex: 16 | return artCursor(val, index, reverse, start, limit); 17 | } 18 | 19 | fprintf(stderr, "Error: makeCursor => invalid index type => %d\n", index->arena->type); 20 | s.bits = vt_status; 21 | s.status = ERROR_script_internal; 22 | return s; 23 | } 24 | 25 | // find correct document from snapshot and key value 26 | 27 | bool cursorFindDoc(DbMap *index, DbCursor *cursor, KeySuffix *suffix) { 28 | RedBlack *entry = index->entry; 29 | uint8_t key[sizeof(ChildMap)]; 30 | KeyVersion *keyVer; 31 | ChildMap *child; 32 | DbDoc *doc; 33 | 34 | child = (ChildMap *)(entry->key + entry->keyLen); 35 | 36 | cursor->docId.bits = get64(suffix->docId); 37 | cursor->keyVer = get64(suffix->keyVer); 38 | 39 | // find document version per timestamp 40 | 41 | if ((cursor->docAddr.bits = findDocVer(index->parent, cursor->docId, cursor->txnId, cursor->timestamp))) 42 | doc = getObj(index->parent, cursor->docAddr); 43 | else 44 | return false; 45 | 46 | // see if key version was inserted for this document 47 | 48 | store64(key, child->id); 49 | if ((entry = rbFind (index->parent, doc->keyActv, key, sizeof(key), NULL))) 50 | keyVer = (KeyVersion *)(entry->key + entry->keyLen); 51 | else 52 | return false; 53 | 54 | if (keyVer->ver == cursor->keyVer) 55 | return true; 56 | 57 | return false; 58 | } 59 | 60 | value_t cursorNext(DbCursor *cursor, DbMap *index) 61 | { 62 | value_t slot; 63 | DbDoc *doc; 64 | 65 | switch (index->arena->type) { 66 | case Hndl_artIndex: { 67 | ArtCursor *artCursor = (ArtCursor *)cursor; 68 | 69 | while (artNextKey(artCursor, index)) 70 | if (cursorFindDoc(index, cursor, artCursorSuffix(artCursor))) { 71 | doc = getObj(index->parent, cursor->docAddr); 72 | slot.bits = vt_document; 73 | slot.document = (document_t *)(doc + 1); 74 | return slot; 75 | } 76 | 77 | slot.bits = vt_undef; 78 | return slot; 79 | } 80 | 81 | case Hndl_btreeIndex: { 82 | BtreeCursor *btreeCursor = (BtreeCursor *)cursor; 83 | 84 | while ((btreeNextKey(btreeCursor, index))) 85 | if (cursorFindDoc(index, cursor, btreeCursorSuffix(btreeCursor))) { 86 | doc = getObj(index->parent, cursor->docAddr); 87 | slot.bits = vt_document; 88 | slot.document = (document_t *)(doc + 1); 89 | return slot; 90 | } 91 | 92 | slot.bits = vt_undef; 93 | return slot; 94 | } 95 | } 96 | 97 | fprintf(stderr, "Error: nextKey => invalid index type: %d\n", index->arena->type); 98 | slot.bits = vt_status; 99 | slot.status = ERROR_script_internal; 100 | return slot; 101 | } 102 | 103 | value_t cursorPrev(DbCursor *cursor, DbMap *index) 104 | { 105 | value_t slot; 106 | DbDoc *doc; 107 | 108 | switch (index->arena->type) { 109 | case Hndl_artIndex: { 110 | ArtCursor *artCursor = (ArtCursor *)cursor; 111 | 112 | while (artPrevKey(artCursor, index)) 113 | if (cursorFindDoc(index, cursor, artCursorSuffix(artCursor))) { 114 | doc = getObj(index->parent, cursor->docAddr); 115 | slot.bits = vt_document; 116 | slot.document = (document_t *)(doc + 1); 117 | return slot; 118 | } 119 | 120 | slot.bits = vt_undef; 121 | return slot; 122 | } 123 | 124 | case Hndl_btreeIndex: { 125 | BtreeCursor *btreeCursor = (BtreeCursor *)cursor; 126 | 127 | while ((btreePrevKey(btreeCursor, index))) 128 | if (cursorFindDoc(index, cursor, btreeCursorSuffix(btreeCursor))) { 129 | doc = getObj(index->parent, cursor->docAddr); 130 | slot.bits = vt_document; 131 | slot.document = (document_t *)(doc + 1); 132 | return slot; 133 | } 134 | 135 | slot.bits = vt_undef; 136 | return slot; 137 | } 138 | } 139 | 140 | fprintf(stderr, "Error: prevKey => invalid index type: %d\n", index->arena->type); 141 | slot.bits = vt_status; 142 | slot.status = ERROR_script_internal; 143 | return slot; 144 | } 145 | -------------------------------------------------------------------------------- /systemMath.js: -------------------------------------------------------------------------------- 1 | // implement Math system object 2 | 3 | var Math = {}; 4 | 5 | // engine implemented functions 6 | 7 | Math._ops = enum { 8 | acos, 9 | acosh, 10 | asin, 11 | asinh, 12 | atan, 13 | atanh, 14 | atan2, 15 | cbrt, 16 | ceil, 17 | clz32, 18 | cos, 19 | cosh, 20 | exp, 21 | expm1, 22 | floor, 23 | fround, 24 | imul, 25 | log, 26 | log1p, 27 | log10, 28 | log2, 29 | pow, 30 | random, 31 | round, 32 | sign, 33 | sin, 34 | sinh, 35 | sqrt, 36 | tan, 37 | tanh, 38 | trunc 39 | }; 40 | 41 | Math.E = 2.7182818284590452354; // e 42 | Math.LOG2E = 1.4426950408889634074; // log_2 e 43 | Math.LOG10E = 0.43429448190325182765; // log_10 e 44 | Math.LN2 = 0.69314718055994530942; // log_e 2 45 | Math.LN10 = 2.30258509299404568402; // log_e 10 46 | Math.PI = 3.14159265358979323846; // pi 47 | Math.PI_2 = 1.57079632679489661923; // pi/2 48 | Math.PI_4 = 0.78539816339744830962; // pi/4 49 | Math.SQRT2 = 1.41421356237309504880; // sqrt(2) 50 | Math.SQRT1_2 = 0.70710678118654752440; // 1/sqrt(2) 51 | 52 | Math.max = function() { 53 | var max = -Infinity, idx; 54 | 55 | for (idx = 0; idx < arguments.length; idx += 1) 56 | if (arguments[idx] > max) 57 | max = arguments[idx]; 58 | 59 | return max; 60 | }; 61 | 62 | Math.min = function() { 63 | var max = Infinity, idx; 64 | 65 | for (idx = 0; idx < arguments.length; idx += 1) 66 | if (arguments[idx] < max) 67 | max = arguments[idx]; 68 | 69 | return max; 70 | }; 71 | 72 | Math.hypot = function() { 73 | var sum = 0.0, idx; 74 | 75 | for (idx = 0; idx < arguments.length; idx += 1) 76 | sum += arguments[idx] * arguments[idx]; 77 | 78 | return Math.sqrt(sum); 79 | }; 80 | 81 | Math.abs = function(x) { 82 | if (x < 0) 83 | return -x; 84 | 85 | return x; 86 | }; 87 | 88 | Math.acos = function() { return jsdb_mathop(arguments, Math._ops.acos); }; 89 | Math.acosh = function() { return jsdb_mathop(arguments, Math._ops.acosh); }; 90 | Math.asin = function() { return jsdb_mathop(arguments, Math._ops.asin); }; 91 | Math.asinh = function() { return jsdb_mathop(arguments, Math._ops.asinh); }; 92 | Math.atan = function() { return jsdb_mathop(arguments, Math._ops.atan); }; 93 | Math.atanh = function() { return jsdb_mathop(arguments, Math._ops.atanh); }; 94 | Math.atan2 = function() { return jsdb_mathop(arguments, Math._ops.atan2); }; 95 | Math.cbrt = function() { return jsdb_mathop(arguments, Math._ops.cbrt); }; 96 | Math.ceil = function() { return jsdb_mathop(arguments, Math._ops.ceil); }; 97 | Math.clz32 = function() { return jsdb_mathop(arguments, Math._ops.clz32); }; 98 | Math.cos = function() { return jsdb_mathop(arguments, Math._ops.cos); }; 99 | Math.cosh = function() { return jsdb_mathop(arguments, Math._ops.cosh); }; 100 | Math.exp = function() { return jsdb_mathop(arguments, Math._ops.exp); }; 101 | Math.expm1 = function() { return jsdb_mathop(arguments, Math._ops.expm1); }; 102 | Math.floor = function() { return jsdb_mathop(arguments, Math._ops.floor); }; 103 | Math.fround = function() { return jsdb_mathop(arguments, Math._ops.fround); }; 104 | Math.imul = function() { return jsdb_mathop(arguments, Math._ops.imum); }; 105 | Math.log = function() { return jsdb_mathop(arguments, Math._ops.log); }; 106 | Math.log1p = function() { return jsdb_mathop(arguments, Math._ops.log1p); }; 107 | Math.log10 = function() { return jsdb_mathop(arguments, Math._ops.log10); }; 108 | Math.log2 = function() { return jsdb_mathop(arguments, Math._ops.log2); }; 109 | Math.pow = function() { return jsdb_mathop(arguments, Math._ops.pow); }; 110 | Math.random = function() { return jsdb_mathop(arguments, Math._ops.random); }; 111 | Math.round = function() { return jsdb_mathop(arguments, Math._ops.round); }; 112 | Math.sign = function() { return jsdb_mathop(arguments, Math._ops.sign); }; 113 | Math.sin = function() { return jsdb_mathop(arguments, Math._ops.sin); }; 114 | Math.sinh = function() { return jsdb_mathop(arguments, Math._ops.sinh); }; 115 | Math.sqrt = function() { return jsdb_mathop(arguments, Math._ops.sqrt); }; 116 | Math.tan = function() { return jsdb_mathop(arguments, Math._ops.tan); }; 117 | Math.tanh = function() { return jsdb_mathop(arguments, Math._ops.tanh); }; 118 | Math.trunc = function() { return jsdb_mathop(arguments, Math._ops.trunc); }; 119 | -------------------------------------------------------------------------------- /js_dbcursor.c: -------------------------------------------------------------------------------- 1 | #include "js.h" 2 | #include "js_props.h" 3 | 4 | #include "js_db.h" 5 | #include "js_dbindex.h" 6 | 7 | #define INT_key 12 // max extra bytes creates 8 | 9 | 10 | // move cursor 11 | 12 | value_t fcnCursorMove (value_t *args, value_t thisVal, environment_t *env) { 13 | DbCursor *dbCursor; 14 | DbMap *map, *docMap; 15 | Handle *idxHndl; 16 | value_t op, val, s; 17 | s.bits = vt_status; 18 | ObjId docId; 19 | 20 | if ((idxHndl = js_handle(thisVal, Hndl_cursor))) 21 | dbCursor = ClntAddr(idxHndl); 22 | else 23 | return s.status = DB_ERROR_handleclosed, s; 24 | 25 | op = conv2Int(args[0], false); 26 | map = MapAddr(idxHndl); 27 | docMap = map->parent; 28 | 29 | if ((s.status = moveCursor(idxHndl->hndl, op.nval))) 30 | return s; 31 | 32 | if ((docId.bits = dbGetDocId(dbCursor))) { 33 | val.bits = vt_docId; 34 | val.idBits = docId.bits; 35 | val.hndlIdx = idxHndl->hndlIdx; 36 | } else { 37 | val.bits = vt_status; 38 | val.status = DB_OK; 39 | } 40 | 41 | releaseHandle(idxHndl); 42 | return val; 43 | } 44 | 45 | value_t fcnCursorPos(value_t *args, value_t thisVal, environment_t *env) { 46 | value_t op, val, key; 47 | DbCursor *dbCursor; 48 | Handle *idxHndl; 49 | DbMap *docMap; 50 | string_t *str; 51 | ObjId docId; 52 | 53 | val.bits = vt_status; 54 | 55 | if (!(idxHndl = js_handle(thisVal, Hndl_cursor))) 56 | return val.status = DB_ERROR_handleclosed, val; 57 | else 58 | docMap = (MapAddr(idxHndl))->parent; 59 | 60 | dbCursor = ClntAddr(idxHndl); 61 | 62 | op = conv2Int(args[0], false); 63 | key = conv2Str(args[1], false, false); 64 | str = js_dbaddr(key, NULL); 65 | 66 | val.status = dbFindKey(dbCursor, docMap, str->val, str->len, op.nval); 67 | 68 | if(!val.status) 69 | if ((docId.bits = dbGetDocId(dbCursor))) { 70 | val.bits = vt_docId; 71 | val.idBits = docId.bits; 72 | val.hndlIdx = idxHndl->hndlIdx; 73 | } 74 | 75 | return val; 76 | } 77 | 78 | value_t fcnCursorKeyAt(value_t *args, value_t thisVal, environment_t *env) { 79 | uint32_t keyLen; 80 | value_t s, val, cursor; 81 | uint8_t *keyStr; 82 | 83 | cursor = thisVal; 84 | s.bits = vt_status; 85 | 86 | while (cursor.type == vt_object) 87 | cursor = *cursor.oval->baseVal; 88 | 89 | if ((s.status = keyAtCursor(cursor.hndl, &keyStr, &keyLen))) 90 | return s; 91 | 92 | val = newString(keyStr, keyLen); 93 | val.type = vt_key; 94 | return val; 95 | } 96 | 97 | value_t fcnCursorDocIdAt(value_t *args, value_t thisVal, environment_t *env) { 98 | value_t val; 99 | DbCursor *dbCursor; 100 | ObjId docId; 101 | Handle *idxHndl; 102 | DbMap *docMap; 103 | 104 | val.bits = vt_status; 105 | 106 | if (!(idxHndl = js_handle(thisVal, Hndl_cursor))) 107 | return val.status = DB_ERROR_handleclosed, val; 108 | else 109 | docMap = (MapAddr(idxHndl))->parent; 110 | 111 | dbCursor = ClntAddr(idxHndl); 112 | 113 | if ((docId.bits = dbGetDocId(dbCursor))) { 114 | val.bits = vt_docId; 115 | val.idBits = docId.bits; 116 | val.hndlIdx = idxHndl->hndlIdx; 117 | } else 118 | val.status = DB_CURSOR_notpositioned; 119 | 120 | releaseHandle(idxHndl); 121 | return val; 122 | } 123 | 124 | // clear cursor 125 | 126 | value_t fcnCursorReset(value_t *args, value_t thisVal, environment_t *env) { 127 | DbCursor *dbCursor; 128 | Handle *idxHndl; 129 | uint64_t bits; 130 | DbMap *map; 131 | DbAddr next; 132 | value_t s; 133 | 134 | s.bits = vt_status; 135 | 136 | if ((idxHndl = js_handle(thisVal, Hndl_cursor))) 137 | map = MapAddr(idxHndl); 138 | else 139 | return s.status = DB_ERROR_handleclosed, s; 140 | 141 | dbCursor = ClntAddr(idxHndl); 142 | bits = dbCursor->deDupHash.bits; 143 | 144 | // clear deDup hash table 145 | 146 | while ((next.bits = bits)) { 147 | DbMmbr *mmbr = getObj(map->parent, next); 148 | bits = mmbr->next.bits; 149 | 150 | freeBlk(map->parent, next); 151 | } 152 | 153 | s.status = dbLeftKey(dbCursor, map); 154 | releaseHandle(idxHndl); 155 | return s; 156 | } 157 | 158 | PropFcn builtinCursorFcns[] = { 159 | { fcnCursorPos, "pos" }, 160 | { fcnCursorMove, "move" }, 161 | { fcnCursorKeyAt, "keyAt" }, 162 | { fcnCursorDocIdAt, "docIdAt" }, 163 | { fcnCursorReset, "reset" }, 164 | { NULL, NULL} 165 | }; 166 | 167 | PropVal builtinCursorProp[] = { 168 | // { propIdxOnDisk, "onDisk" }, 169 | { NULL, NULL} 170 | }; 171 | -------------------------------------------------------------------------------- /oldjsdb/jsdb_dbartdelete.c: -------------------------------------------------------------------------------- 1 | #include "jsdb.h" 2 | #include "jsdb_db.h" 3 | 4 | typedef enum { 5 | ContinueSearch, 6 | EndSearch, 7 | RetrySearch, 8 | RestartSearch, 9 | ErrorSearch 10 | } ReturnState; 11 | 12 | Status artDeleteKey(DbMap *index, uint32_t set, ArtCursor *cursor) { 13 | DbAddr *slot, newSlot; 14 | ReturnState rt; 15 | uint32_t bit; 16 | uint8_t ch; 17 | 18 | // now that we have the trie nodes in the cursor stack 19 | // we can go through them backwards to remove empties. 20 | 21 | while (cursor->depth) { 22 | CursorStack *stack = &cursor->stack[--cursor->depth]; 23 | uint32_t pass = 0; 24 | bool retry = true; 25 | 26 | ch = stack->ch; 27 | slot = stack->addr; 28 | 29 | // wait if we run into a dead slot 30 | do { 31 | if (pass) 32 | art_yield(); 33 | else 34 | pass = 1; 35 | 36 | // obtain write lock on the node 37 | lockLatch(slot->latch); 38 | newSlot.bits = stack->addr->bits; 39 | 40 | if ((retry = newSlot.dead)) 41 | unlockLatch(slot->latch); 42 | 43 | } while (retry); 44 | 45 | switch (newSlot.type < SpanNode ? newSlot.type : SpanNode) { 46 | case UnusedSlot: { 47 | rt = EndSearch; 48 | break; 49 | } 50 | case KeyEnd: { 51 | rt = EndSearch; 52 | break; 53 | } 54 | 55 | case SpanNode: { 56 | kill_slot(slot->latch); 57 | 58 | if (!addSlotToWaitList(index, set, newSlot)) 59 | rt = ErrorSearch; 60 | else 61 | rt = ContinueSearch; 62 | 63 | break; 64 | } 65 | case Array4: { 66 | ARTNode4 *node = getObj(index, *stack->addr); 67 | 68 | for (bit = 0; bit < 4; bit++) { 69 | if (node->alloc & (1 << bit)) 70 | if (ch == node->keys[bit]) 71 | break; 72 | } 73 | 74 | if (bit == 4) { 75 | rt = EndSearch; // key byte not found 76 | break; 77 | } 78 | 79 | // we are not the last entry in the node? 80 | 81 | node->alloc &= ~(1 << bit); 82 | 83 | if (node->alloc) { 84 | rt = EndSearch; 85 | break; 86 | } 87 | 88 | kill_slot(slot->latch); 89 | 90 | if (!addSlotToWaitList(index, set, newSlot)) { 91 | rt = ErrorSearch; 92 | break; 93 | } 94 | 95 | rt = ContinueSearch; 96 | break; 97 | } 98 | case Array14: { 99 | ARTNode14 *node = getObj(index, *stack->addr); 100 | 101 | for (bit = 0; bit < 14; bit++) { 102 | if (node->alloc & (1 << bit)) 103 | if (ch == node->keys[bit]) 104 | break; 105 | } 106 | 107 | if (bit == 14) { 108 | rt = EndSearch; // key byte not found 109 | break; 110 | } 111 | 112 | // we are not the last entry in the node? 113 | 114 | node->alloc &= ~(1 << bit); 115 | 116 | if (node->alloc) { 117 | rt = EndSearch; 118 | break; 119 | } 120 | 121 | kill_slot(slot->latch); 122 | 123 | if (!addSlotToWaitList(index, set, newSlot)) 124 | rt = ErrorSearch; 125 | else 126 | rt = ContinueSearch; 127 | 128 | break; 129 | } 130 | 131 | case Array64: { 132 | ARTNode64 *node = getObj(index, *stack->addr); 133 | bit = node->keys[ch]; 134 | 135 | if (bit == 0xff) { 136 | rt = EndSearch; 137 | break; 138 | } 139 | 140 | node->keys[ch] = 0xff; 141 | node->alloc &= ~(1ULL << bit); 142 | 143 | if (node->alloc) { 144 | rt = EndSearch; 145 | break; 146 | } 147 | 148 | kill_slot(slot->latch); 149 | 150 | if (!addSlotToWaitList(index, set, newSlot)) 151 | rt = ErrorSearch; 152 | else 153 | rt = ContinueSearch; 154 | 155 | break; 156 | } 157 | 158 | case Array256: { 159 | ARTNode256 *node = getObj(index, *stack->addr); 160 | bit = ch; 161 | 162 | if (~node->alloc[bit / 64] & (1ULL << (bit % 64))) { 163 | rt = EndSearch; 164 | break; 165 | } 166 | 167 | node->alloc[bit / 64] &= ~(1ULL << (bit % 64)); 168 | 169 | if (node->alloc[0] | node->alloc[1] | node->alloc[2] | node->alloc[3]) { 170 | rt = EndSearch; 171 | break; 172 | } 173 | 174 | kill_slot(slot->latch); 175 | 176 | if (!addSlotToWaitList(index, set, newSlot)) 177 | rt = ErrorSearch; 178 | else 179 | rt = ContinueSearch; 180 | 181 | break; 182 | } 183 | } // end switch 184 | 185 | unlockLatch(stack->addr->latch); 186 | 187 | if (rt == ContinueSearch) 188 | continue; 189 | 190 | break; 191 | 192 | } // end while 193 | 194 | // zero out root? 195 | 196 | if (!cursor->depth && rt == ContinueSearch) 197 | slot->bits = 0; 198 | 199 | atomicAdd64(artIndexAddr(index)->numEntries, -1); 200 | return OK; 201 | } 202 | -------------------------------------------------------------------------------- /oldjsdb/jsdb_rwlock2.c: -------------------------------------------------------------------------------- 1 | // Simple Reader/Writer lock 2 | 3 | #ifdef linux 4 | #define _GNU_SOURCE 5 | #include 6 | #include 7 | #endif 8 | 9 | #ifndef _WIN32 10 | #include 11 | #endif 12 | 13 | #include "jsdb.h" 14 | #include "jsdb_db.h" 15 | 16 | #ifdef linux 17 | #include 18 | #include 19 | 20 | int sys_futex(volatile uint32_t *addr1, int op, int val1, struct timespec *timeout, void *addr2, int val3) 21 | { 22 | return syscall(SYS_futex, addr1, op, val1, timeout, addr2, val3); 23 | } 24 | 25 | #define pause() asm volatile("pause\n": : : "memory") 26 | #endif 27 | 28 | void WriteLock(RWLock *lock, SpinType spin) 29 | { 30 | uint32_t backoff = 16; 31 | RWLock prev; 32 | int idx; 33 | 34 | while (1) { 35 | #ifndef _WIN32 36 | prev.bits = __sync_fetch_and_or (lock->mutex, WRITER); 37 | #else 38 | prev.bits = _InterlockedOr (lock->mutex, WRITER); 39 | #endif 40 | while (prev.writer) { 41 | // wait for readers to reach zero 42 | 43 | if (!prev.readers) 44 | return; 45 | 46 | if (spin == SpinLock) { 47 | for (idx = 0; idx < backoff; idx++) { 48 | if (lock->readers) 49 | return; 50 | #ifdef _WIN32 51 | YieldProcessor(); 52 | #else 53 | pause(); 54 | #endif 55 | } 56 | 57 | if (backoff < 16*1024*1024) 58 | backoff *= 2; 59 | 60 | continue; 61 | } 62 | // wait for zero reader count 63 | #ifdef linux 64 | prev.waitwrt2 = 1; 65 | __sync_fetch_and_or (lock->mutex, WAITWRT2); 66 | sys_futex (lock->mutex, FUTEX_WAIT_BITSET, prev.bits, NULL, NULL, WaitWrt2); 67 | #elif defined(_WIN32) 68 | SwitchToThread(); 69 | #else 70 | sched_yield(); 71 | #endif 72 | } 73 | 74 | // wait for writer mutex 75 | #ifdef linux 76 | prev.waitwrt1 = 1; 77 | __sync_fetch_and_or (lock->mutex, WAITWRT1); 78 | sys_futex (lock->mutex, FUTEX_WAIT_BITSET, prev.bits, NULL, NULL, WaitWrt1); 79 | #elif defined(_WIN32) 80 | SwitchToThread(); 81 | #else 82 | sched_yield(); 83 | #endif 84 | } 85 | } 86 | 87 | void rwUnlock(RWLock *lock, RWType type) 88 | { 89 | RWLock prev; 90 | 91 | if (type == RWWrite) { 92 | // release write lock 93 | #ifndef _WIN32 94 | prev.bits = __sync_fetch_and_and (lock->mutex, ~WRITER); 95 | #else 96 | prev.bits = _InterlockedAnd (lock->mutex, ~WRITER); 97 | #endif 98 | 99 | #ifdef linux 100 | if (prev.bits & WAITRD) { 101 | __sync_fetch_and_and (lock->mutex, ~WAITRD); 102 | sys_futex (lock->mutex, FUTEX_WAKE_BITSET, INT_MAX, NULL, NULL, WaitRd); 103 | } else if (prev.bits & WAITWRT1) { 104 | __sync_fetch_and_and (lock->mutex, ~WAITWRT1); 105 | sys_futex (lock->mutex, FUTEX_WAKE_BITSET, 1, NULL, NULL, WaitWrt1); 106 | } 107 | #endif 108 | return; 109 | } else { 110 | // release read lock 111 | 112 | #ifndef _WIN32 113 | prev.bits = __sync_fetch_and_add (lock->mutex, -READER) - READER; 114 | #else 115 | prev.bits = _InterlockedAdd (lock->mutex, -READER); 116 | #endif 117 | if (prev.readers) 118 | return; 119 | #ifdef linux 120 | if (prev.bits & WAITWRT2) { 121 | __sync_fetch_and_and (lock->mutex, ~WAITWRT2); 122 | sys_futex (lock->mutex, FUTEX_WAKE_BITSET, 1, NULL, NULL, WaitWrt2); 123 | } 124 | #endif 125 | } 126 | } 127 | 128 | void readLock (RWLock *lock, SpinType spin) 129 | { 130 | uint32_t backoff; 131 | RWLock prev; 132 | int idx; 133 | 134 | while ((backoff = 16)) { 135 | // wait until writer unlocks 136 | 137 | while ((lock->writer)) { 138 | if (spin == SpinLock) { 139 | for (idx = 0; idx < backoff; idx++) 140 | #ifdef _WIN32 141 | YieldProcessor(); 142 | #else 143 | pause(); 144 | #endif 145 | if (backoff < 16*1024*1024) 146 | backoff *= 2; 147 | } else { 148 | for (idx = 0; idx < backoff; idx++) 149 | #ifdef _WIN32 150 | YieldProcessor(); 151 | #else 152 | pause(); 153 | #endif 154 | if (!backoff) 155 | continue; 156 | 157 | backoff = 0; 158 | #ifdef linux 159 | prev.bits = __sync_fetch_and_or (lock->mutex, WAITRD); 160 | prev.waitrd = 1; 161 | sys_futex (lock->mutex, FUTEX_WAIT_BITSET, prev.bits, NULL, NULL, WaitRd); 162 | #elif defined(_WIN32) 163 | SwitchToThread(); 164 | #else 165 | sched_yield(); 166 | #endif 167 | } 168 | } 169 | // if writers gone, 170 | // take reader lock 171 | 172 | #ifndef _WIN32 173 | __sync_fetch_and_add (lock->mutex, READER); 174 | #else 175 | _InterlockedAdd (lock->mutex, READER); 176 | #endif 177 | if (!lock->writer) 178 | return; 179 | 180 | // otherwise, try again from the top 181 | 182 | #ifndef _WIN32 183 | __sync_fetch_and_add (lock->mutex, -READER); 184 | #else 185 | _InterlockedAdd (lock->mutex, -READER); 186 | #endif 187 | } 188 | } 189 | --------------------------------------------------------------------------------