![]() System : Linux absol.cf 5.4.0-198-generic #218-Ubuntu SMP Fri Sep 27 20:18:53 UTC 2024 x86_64 User : www-data ( 33) PHP Version : 7.4.33 Disable Function : pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,pcntl_unshare, Directory : /var/www/html/keeview_app/html/ |
Upload File : |
const fcache = Object.freeze(function () { var fcache_retval = {}; var fcore = {}; var dbver = 6; var debugPrintFlag = false; if (navigator.platform !== undefined) { if (navigator.platform.toLowerCase() == "iphone") { fcore.workMode = "idb"; } } if (window.androidfs !== undefined) { if (androidfs.support()) { fcore.workMode = "android"; } } if (fcore.workMode === undefined) { fs.support(function (retval) { if (retval === true) { fcore.workMode = "fsapi"; } else { fcore.workMode = "idb"; } }); } fcore.mkdir = function (callbackfunc, core, pathname) { if (fcore.workMode === undefined) { Thread.wait( function () { return fcore.workMode !== undefined; }, function () { Thread.setTimeout({ func: fcore.mkdir, args: [callbackfunc, core.dbname, pathname] }); } ); return; } switch (fcore.workMode) { case "android": androidfs.mkdir(core.dbname + "_fsdb_" + pathname, callbackfunc); return; case "fsapi": fs.mkdir(callbackfunc, core.dbname + "_fsdb_" + pathname); return; case "idb": if (core.connectors === undefined) core.connectors = {}; if (core.connectors[core.dbname] === undefined) { idbfs.open("fsdb_" + core.dbname, function (success, content) { core.connectors[core.dbname] = content; Thread.setTimeout({ func: fcore.mkdir, args: [callbackfunc, core, pathname] }); }); return; } if (pathname.trim().length == 0) { Thread.setTimeout({ func: callbackfunc, args: [true] }); return; } core.connectors[core.dbname].mkdir(pathname, function () { callbackfunc(true); }); } } fcore.sameArray = function (arr1, arr2) { var i; if ((arr1 === undefined) && (arr2 !== undefined)) return false; if ((arr2 === undefined) && (arr1 !== undefined)) return false; if (arr1.length != arr2.length) return false; for (i = 0; i < arr1.length; i++) { if (arr1[i] != arr2[i]) return false; } return true; } fcore.getFormat = function (data) { var format = Object.keys(data); format.sort(); return format; } fcore.fromFormat = function (format, data) { var r = []; var i; for (i = 0; i < format.length; i++) { r.push(data[format[i]]); } return r; } fcore.toFormat = function (format, data) { var r = {}; var i; for (i = 0; i < format.length; i++) { r[format[i]] = data[i]; } return r; } fcore.defaultConfig = function (dbname, fieldList) { var r = { lastid: 0, lastuts: -1, fieldList: fieldList, chksum: EncodingClass.md5.encode(EncodingClass.string.fromVariable({ lastid: 0, lastuts: -1, format: undefined }) + "_" + dbname + "_" + dbver) }; return r; } fcore.resetTable = function (core, tablename, callbackfunc) { var options = core.tables[tablename].options; var mode = core.tables[tablename].mode; var fieldList; if (options !== undefined) { fieldList = options.fieldList; } core.tables[tablename] = { mode: mode, config: fcore.defaultConfig(core.dbname, fieldList), data: [], options: options, c1: 0, c2: 0, c3: 0 }; if (mode == "block") { core.tables[tablename].hostdata = []; core.tables[tablename].hostmodified = []; } fcore.resetCache(core, tablename, function () { Thread.setTimeout({ func: core.init, args: [tablename, mode, callbackfunc, options] }); }); } fcore.preinit = function (core, tablename, mode, options, callbackfunc, success, content) { var fieldList; if (options !== undefined) { if (options.fieldList !== undefined) { options.fieldList.sort(); fieldList = options.fieldList; } } if (!success) { if (debugPrintFlag) console.log("Can not open table " + tablename, content); Thread.setTimeout({ func: callbackfunc, args: [false] }); return false; } core.tables[tablename] = { mode: mode, config: fcore.defaultConfig(core.dbname, fieldList), data: [], options: options }; if (mode == "block") { core.tables[tablename].hostdata = []; core.tables[tablename].hostmodified = []; } return true; } fcore.init = function (core, tablename, options, callbackfunc, success, content) { var i, keyList = []; var keyMark = {}; if (!success) { if (debugPrintFlag) console.log("Can not open table " + tablename, content); Thread.setTimeout({ func: callbackfunc, args: [false] }); return; } for (i = 0; i < content.length; i++) { if (content[i].type == "file") { keyList.push(content[i].name); keyMark[content[i].name] = true; } } if (keyMark["config"] !== undefined) { Thread.setTimeout({ func: core.fetchConfigFromCache, args: [keyList, tablename, callbackfunc] }); } else { Thread.setTimeout({ func: core.fetchDataFromServer, args: [tablename, callbackfunc, 0, 0, 0] }); } } fcore.fsinit = function (core, dbname) { return function (tablename, mode, callbackfunc, options) { if (core.inited[tablename] === undefined) core.inited[tablename] = null; fcore.mkdir(function (tablename, mode, callbackfunc) { return function (success, content) { if (!fcore.preinit(core, tablename, mode, options, callbackfunc, success, content)) return; fs.readDir(function (success, content) { fcore.init(core, tablename, options, callbackfunc, success, content); }, core.dbname + "_fsdb_" + tablename); } } (tablename, mode, callbackfunc), core, tablename); } } fcore.androidinit = function (core, dbname) { return function (tablename, mode, callbackfunc, options) { if (core.inited[tablename] === undefined) core.inited[tablename] = null; fcore.mkdir(function (tablename, mode, callbackfunc) { return function (success, content) { if (!fcore.preinit(core, tablename, mode, options, callbackfunc, success, content)) return; androidfs.readDir(core.dbname + "_fsdb_" + tablename, function (success, content) { fcore.init(core, tablename, options, callbackfunc, success, content); }); } } (tablename, mode, callbackfunc), core, tablename); } } fcore.idbinit = function (core, dbname) { return function (tablename, mode, callbackfunc, options) { var fieldList; if (options !== undefined) { fieldList = options.fieldList; } if (core.inited[tablename] === undefined) core.inited[tablename] = null; fcore.mkdir(function (tablename, mode, callbackfunc) { return function (success, content) { if (!fcore.preinit(core, tablename, mode, options, callbackfunc, success, content)) return; core.connectors[core.dbname].readDir(tablename, function (content) { fcore.init(core, tablename, options, callbackfunc, true, content); }); } } (tablename, mode, callbackfunc), core, tablename); } } fcore.getTableFields = function (core, tablename, configvalue, callbackfunc) { core.apiqueue.push({ url: core.url, params: [ { name: "task", value: "format" }, { name: "name", value: tablename }, { name: "lastid", value: 0 }, { name: "lastuts", value: 0 } ], func: function (core, tablename, configvalue, callbackfunc) { return function (success, data) { var i, sindex, slen, name, flist, fmark; if (success) { sindex = 0; flist = []; while (sindex < data.length) { slen = EncodingClass.number.fromArray("i32", data, sindex); sindex += 4; name = EncodingClass.string.fromUint8Array(data, sindex, slen); sindex += slen; name = EncodingClass.utf8.decode(name); flist.push(name); } flist.sort(); fmark = {}; for (i = 0; i < flist.length; i++) { fmark[flist[i]] = true; } if (configvalue.format === undefined) { console.log("format not found [" + tablename + "]"); Thread.setTimeout({ func: callbackfunc, args: [false, flist, "format not found"] }); return; } if (configvalue.fieldList === undefined) { for (i = 0; i < configvalue.format.length; i++) { name = configvalue.format[i]; if (fmark[name] === undefined) { console.log("database changed [" + tablename + "]"); Thread.setTimeout({ func: callbackfunc, args: [false, flist, "database changed"] }); return; } delete fmark[name]; } if (Object.keys(fmark).length > 0) { console.log("database changed [" + tablename + "]"); Thread.setTimeout({ func: callbackfunc, args: [false, flist, "database changed"] }); return; } Thread.setTimeout({ func: callbackfunc, args: [true, flist] }); } else { for (i = 0; i < configvalue.fieldList.length; i++) { name = configvalue.fieldList[i]; if (fmark[name] === undefined) { console.log("database changed [" + tablename + "]"); Thread.setTimeout({ func: callbackfunc, args: [false, configvalue.fieldList, "database changed"] }); return; } delete fmark[name]; } Thread.setTimeout({ func: callbackfunc, args: [true, configvalue.fieldList] }); } } else { Thread.setTimeout({ func: fcore.getTableFields, args: [core, tablename, configvalue, callbackfunc], time: 5000 }); } } } (core, tablename, configvalue, callbackfunc) }); } fcore.resetCache = function (core, tablename, callbackfunc) { var pathname, xfunc; xfunc = function (callbackfunc) { return function () { console.log("cache removed [" + tablename + "]"); callbackfunc(); } } (callbackfunc); switch (fcore.workMode) { case "android": pathname = core.dbname + "_fsdb_" + tablename; androidfs.remove(pathname, function () { androidfs.mkdir(pathname, xfunc); }); return; case "fsapi": pathname = core.dbname + "_fsdb_" + tablename; fs.remove(function () { fs.mkdir(xfunc, pathname); }, pathname); return; case "idb": core.connectors[core.dbname].remove(tablename, function () { core.connectors[core.dbname].mkdir(tablename, xfunc); }); return; } } fcore.readConfig = function (core, keyList, tablename, callbackfunc, success, value) { var ok, i, mark, options; if ((!success) || (value === null)) { value = {}; } else if (value[0] === null) { value = {}; } else if (!value[0].success) { value = {}; } else { value = EncodingClass.number.toVariable(value[0].content); } if (value === undefined) value = {}; if ((value.fieldList === undefined) && (core.tables[tablename].config.fieldList !== undefined)) { ok = false; } else if ((value.fieldList !== undefined) && (core.tables[tablename].config.fieldList === undefined)) { ok = false; } else if (value.fieldList !== undefined) { if (value.fieldList.length != core.tables[tablename].config.fieldList.length) { ok = false; } else { ok = true; mark = {}; for (i = 0; i < value.fieldList.length; i++) { mark[value.fieldList[i]] = true; } for (i = 0; i < core.tables[tablename].config.fieldList.length; i++) { if (mark[core.tables[tablename].config.fieldList[i]] === undefined) { ok = false; break; } } mark = null; } } else { ok = true; } if (ok) { ok = ((success) && (keyList.length > 0) && (EncodingClass.md5.encode(EncodingClass.string.fromVariable({ lastid: value.lastid, lastuts: value.lastuts, format: value.format }) + "_" + core.dbname + "_" + dbver) == value.chksum)); } if (ok) { fcore.getTableFields(core, tablename, value, function (success, format, message) { if (success) { core.tables[tablename].config = value; core.tables[tablename].config.format = format; Thread.setTimeout({ func: core.fetchDataFromCache, args: [keyList, tablename, callbackfunc] }); } else { fcore.resetCache(core, tablename, function () { core.tables[tablename].c1 = 0; core.tables[tablename].c2 = 0; core.tables[tablename].c3 = 0; core.tables[tablename].config.format = format; Thread.setTimeout({ func: core.fetchDataFromServer, args: [tablename, callbackfunc, 0, 0, 0] }); }); } }); } else { options = core.tables[tablename].options; fcore.getTableFields(core, tablename, fcore.defaultConfig(core.dbname, value.fieldList), function (success, format, message) { fcore.resetCache(core, tablename, function () { core.tables[tablename].c1 = 0; core.tables[tablename].c2 = 0; core.tables[tablename].c3 = 0; core.tables[tablename].options = options; core.tables[tablename].config.format = format; Thread.setTimeout({ func: core.fetchDataFromServer, args: [tablename, callbackfunc, 0, 0, 0] }); }); }); } } fcore.readProcess_block = function (name, retval, callbackfunc) { var segno = parseInt(name.substr(1)); var totallength = 0, xlen = 0; var xkey; var start, length, offset, edata = []; var i, j; var v1 = 0, v2 = 0, v3 = 0, uts; xkey = [retval[0], retval[1], retval[2], 0]; ts = EncodingClass.number.rndFunc(0x9E3779B9, 0x243F6A88, 0xB7E15162, EncodingClass.number.fromArray("i32", xkey)); for (i = 3; (i < retval.length) && (i < 5); i++) { retval[i] ^= ts(256); } if (EncodingClass.number.fromArray("i16", retval, 3) != dbver) { callbackfunc({ type: "remove", content: "invalid dbver" }); return; } for (i = 5; i < retval.length; i++) { retval[i] ^= ts(256); } for (start = 5; start < retval.length; start += length + 16) { offset = EncodingClass.number.fromArray("i32", retval, start); length = EncodingClass.number.fromArray("i32", retval, start + 4); uts = EncodingClass.number.fromArray("f64", retval, start + 8); v1 = (((v1 + offset) % 0xFFFFFF) + 0xFFFFFF) % 0xFFFFFF; v2 = (((v2 + uts) % 0xFFFFFF) + 0xFFFFFF) % 0xFFFFFF; v3 = (((v3 + offset*uts) % 0xFFFFFF) + 0xFFFFFF) % 0xFFFFFF; edata.push([offset, start + 4]); } callbackfunc({ type: "data", content: { hostdata: retval, edata: edata, chksum: [v1, v2, v3] } }, [retval.buffer]); } fcore.readProcess_row = function (name, retval, callbackfunc) { var transferList = []; var segno = parseInt(name.substr(1)); var tlen = 0, xlen = 0; var nval, xkey; var start, length, offset, tcontent, tdata = [], offsetList = [], segData = null, edata = []; var i, j, first = -1; var v1 = 0, v2 = 0, v3 = 0, uts; xkey = [retval[0], retval[1], retval[2], 0]; ts = EncodingClass.number.rndFunc(0x9E3779B9, 0x243F6A88, 0xB7E15162, EncodingClass.number.fromArray("i32", xkey)); for (i = 3; (i < retval.length) && (i < 5); i++) { retval[i] ^= ts(256); } if (EncodingClass.number.fromArray("i16", retval, 3) != dbver) { callbackfunc({ type: "remove", content: "invalid dbver" }); return; } for (i = 5; i < retval.length; i++) { retval[i] ^= ts(256); } for (start = 5; start < retval.length; start += length + 16) { offset = EncodingClass.number.fromArray("i32", retval, start); length = EncodingClass.number.fromArray("i32", retval, start + 4) + 8; uts = EncodingClass.number.fromArray("f64", retval, start + 8); segData = new Uint8Array(length); for (i = 0; i < length; i++) { segData[i] = retval[start + 4 + i]; } if (first == -1) first = offset; v1 = (((v1 + offset) % 0xFFFFFF) + 0xFFFFFF) % 0xFFFFFF; v2 = (((v2 + uts) % 0xFFFFFF) + 0xFFFFFF) % 0xFFFFFF; v3 = (((v3 + offset*uts) % 0xFFFFFF) + 0xFFFFFF) % 0xFFFFFF; edata.push([offset, segData]); transferList.push(segData.buffer); } segData = null; retval = null; tdata = null; offsetList = null; callbackfunc({ type: "data", content: { edata: edata, chksum: [v1, v2, v3] } }, transferList); } fcore.pool = Thread.createWorkerPool({ extcode: EncodingClass.exportCode(), modules: { rowfunc: fcore.readProcess_row, blockfunc: fcore.readProcess_block, dbver: dbver }, afunc: function (params, callbackfunc) { switch (params.mode) { case "row": rowfunc(params.name, params.content, callbackfunc); break; case "block": blockfunc(params.name, params.content, callbackfunc); break; default: callbackfunc({ type: "null" }); break; } } }); fcache_retval.open = function (dbname, requesturi, calldataFunc) { var core = { url: "dbload.php", dbname: dbname, inited: {}, tables: {}, apiqueue: [], apiThreadCount: 0, decodequeue: [], decodeWorkerCount: 0 }; var retval = {}; if (requesturi !== undefined) core.url = requesturi; if (calldataFunc !== undefined) core.calldataFunc = calldataFunc; core.mainRnd = EncodingClass.number.rndFunc((new Date()).getTime()); core.init = function (tablename, mode, callbackfunc, options) { Thread.wait( function () { return fcore.workMode !== undefined; }, function () { switch (fcore.workMode) { case "android": core.init = fcore.androidinit(core, dbname); break; case "fsapi": core.init = fcore.fsinit(core, dbname); break; case "idb": core.init = fcore.idbinit(core, dbname); break; } core.init(tablename, mode, callbackfunc, options); } ); } core.promiseInit = function (core) { return function (tablename, mode, options) { var host = {}; Thread.setTimeout({ func: core.init, args: [tablename, mode, function (host) { return function (instance) { host.resolve(instance); } } (host), options] }); return new Promise(function(resolve, reject) { host.resolve = resolve; host.reject = reject; }); } } (core); core.fetchConfigFromCache = function (core) { return function (keyList, tablename, callbackfunc) { switch (fcore.workMode) { case "android": androidfs.readFiles({ path: core.dbname + "_fsdb_" + tablename, list: ["config"], callbackfunc: function (success, value) { if (success) { if (value.length > 0) { value[0].content = EncodingClass.string.fromUint8Array(value[0].content); } } fcore.readConfig(core, keyList, tablename, callbackfunc, success, value); } }); break; case "fsapi": fs.readFiles({ path: core.dbname + "_fsdb_" + tablename, list: ["config"], callbackfunc: function (success, value) { fcore.readConfig(core, keyList, tablename, callbackfunc, success, value); } }); break; case "idb": core.connectors[core.dbname].readFile(tablename + "/config", function (r) { if (r !== null) { r = EncodingClass.string.fromUint8Array(r); fcore.readConfig(core, keyList, tablename, callbackfunc, true, [{ success: true, content: r }]); } else { fcore.readConfig(core, keyList, tablename, callbackfunc, false); } }); break; } } } (core); core.fetchDataFromCacheThread = function (core) { return function (host) { var sname, index; var flist, i, keys, path = []; var v1 = 0, v2 = 0, v3 = 0; var pfunc = function () { if (flist.length == 0) { Thread.setTimeout({ func: core.fetchDataFromServer, args: [host.tablename, host.callbackfunc, v1, v2, v3] }); return; } switch (fcore.workMode) { case "android": androidfs.readFiles({ path: core.dbname + "_fsdb_" + host.tablename, list: [flist[0]], callbackfunc: function (success, content) { var i, j, offset; if (!success) { if (debugPrintFlag) console.log("can not read data"); Thread.setTimeout({ func: perror }); return; } Thread.setTimeout({ func: pfunc2, args: [content[0].content] }); } }); break; case "fsapi": fs.readFiles({ path: core.dbname + "_fsdb_" + host.tablename, list: [flist[0]], mode: "u8", callbackfunc: function (success, content) { var i, j, offset; if (!success) { if (debugPrintFlag) console.log("can not read data"); Thread.setTimeout({ func: perror }); return; } Thread.setTimeout({ func: pfunc2, args: [content[0].content] }); } }); break; case "idb": core.connectors[core.dbname].readFile(host.tablename + "/" + flist[0], function (content) { if (content === null) { if (debugPrintFlag) console.log("can not read data"); Thread.setTimeout({ func: perror }); return; } Thread.setTimeout({ func: pfunc2, args: [content] }); }); break; } }; var pfunc2 = function (content) { //extraParams: {dbver: dbver, path: [core.dbname + "_fsdb_" + host.tablename]}, fcore.pool.acall({ params: { name: flist[0], mode: core.tables[host.tablename].mode, content: content }, transferList: [content.buffer], callbackfunc: function (r) { switch (r.type) { case "null": if (debugPrintFlag) console.log("can not read data"); break; case "remove": switch (fcore.workMode) { case "android": androidfs.remove (core.dbname + "_fsdb_" + host.tablename + "/" + flist[0], function (success, error) { console.log("[" + host.tablename + "] " + r.content + " ]"); Thread.setTimeout({ func: perror }); }); return; case "fsapi": fs.remove (function (success, error) { console.log("[" + host.tablename + "] " + r.content + " ]"); Thread.setTimeout({ func: perror }); }, core.dbname + "_fsdb_" + host.tablename + "/" + flist[0]); return; case "idb": core.connectors[core.dbname].remove(host.tablename + "/" + flist[0], function () { console.log("[" + host.tablename + "] " + r.content + " ]"); Thread.setTimeout({ func: perror }); }); return; } break; case "data": Thread.setTimeout({ func: pfunc3, args: [r.content] }); return; } console.log("Invalid response from cache [" + host.tablename + "] (" + r.type + ")"); Thread.setTimeout({ func: perror }); } }); }; var pfunc3 = function (content) { var index, j; v1 = (v1 + content.chksum[0]) % 0xFFFFFF; v2 = (v2 + content.chksum[1]) % 0xFFFFFF; v3 = (v3 + content.chksum[2]) % 0xFFFFFF; if (core.tables[host.tablename].mode == "block") { index = parseInt(flist[0].substr(1)); core.tables[host.tablename].hostdata[index] = content.hostdata; } for (j = 0; j < content.edata.length; j++) { offset = content.edata[j][0]; core.tables[host.tablename].data[offset] = content.edata[j][1]; } Thread.setTimeout({ func: pnext }); }; var pnext = function () { flist.shift(); Thread.setTimeout({ func: pfunc }); } var perror = function () { Thread.setTimeout({ func: fcore.resetTable, args: [core, host.tablename, host.callbackfunc] }); } flist = EncodingClass.string.duplicateObject(host.keyList); Thread.setTimeout({ func: pfunc }); } } (core); core.fetchDataFromCache = function (core) { return function (kList, tablename, callbackfunc) { var host; var sname, index, keyList = []; var i; if (debugPrintFlag) console.log("fetchDataFromCache", tablename); for (i = 0; i < kList.length; i++) { if (kList[i].substr(0, 1) != "s") continue; index = parseInt(kList[i].substr(1)); if (("s" + index) != kList[i]) continue; keyList.push(kList[i]); } if (keyList.length == 0) { Thread.setTimeout({ func: core.fetchDataFromServer, args: [tablename, callbackfunc, 0, 0, 0] }); return; } host = { tablename: tablename, keyList: keyList, callbackfunc: callbackfunc, queue: [] } Thread.setTimeout({ func: core.fetchDataFromCacheThread, args: [host] }); } } (core); core.apiThread = function (core) { return function () { var calldata; //while ((core.apiqueue.length > 0) && (core.apiThreadCount < 320)) { while (core.apiqueue.length > 0) { calldata = core.apiqueue.shift(); if (core.calldataFunc !== undefined) core.calldataFunc(calldata); calldata.ru8 = true; calldata.func = function (func) { return function (success, contents) { Thread.setTimeout({ func: func, args: [success, contents] }); core.apiThreadCount--; } } (calldata.func); FormClass.zip_call(calldata); core.apiThreadCount++; } Thread.setTimeout({ func: core.apiThread, time: 2 }); } } (core); Thread.setTimeout({func: core.apiThread}); core.decodeFunc = function (params) { var r; var xf, i, j, k, t, s, xlen; var retval = []; transferList = []; params.content = params.content.subarray(1, params.content.length); r = EncodingClass.number.toTable(params.content); for (i = 0; i < r.length; i++) { offset = r[i].id; segment = offset >> 12; if (xf === undefined) { xf = Object.keys(r[i]); xf.sort(); } if (t === undefined) { t = []; for (j = 0; j < xf.length; j++) t.push(null); } xlen = 8; for (j = 0; j < xf.length; j++) { s = EncodingClass.number.fromVariable(r[i][xf[j]]); t[j] = s; xlen += s.length; } if (xlen > 0) { s = new Uint8Array(xlen); EncodingClass.number.writeArray("f64", ~~(r[i].uts.getTime() / 1000), s, 0); xlen = 8; for (j = 0; j < xf.length; j++) { for (k = 0; k < t[j].length; k++) { s[xlen++] = t[j].charCodeAt(k); } } retval.push({ id: offset, uts: r[i].uts, data: s }); transferList.push(s.buffer); } } return { format: xf, data: retval }; } core.decodeBlob = Thread.generateBlob({ extcode: EncodingClass.exportCode(), func: core.decodeFunc }); core.fetchDataFromServer = function (core) { return function (tablename, callbackfunc, c1, c2, c3) { var host = { tablename: tablename, segMark: {}, total: 0, finished: 0, lastindex: -1, callbackfunc: callbackfunc }; host.genCallbackFunc = function (host) { return function (index) { return function (content) { var i, j, k, r, t, segment, offset, start; var uts, lastuts = -1, lastid = 0; var v1 = 0, v2 = 0, v3 = 0, v; r = content.data; if (content.format !== undefined) { if (!fcore.sameArray(core.tables[host.tablename].config.format, content.format)) { core.tables[host.tablename].data = []; if (core.tables[host.tablename].mode == "block") { core.tables[host.tablename].hostdata = []; core.tables[host.tablename].hostmodified = []; } core.tables[host.tablename].config.format = content.format; core.tables[host.tablename].c1 = 0; core.tables[host.tablename].c2 = 0; core.tables[host.tablename].c3 = 0; } } switch (core.tables[host.tablename].mode) { case "row": for (i = 0; i < r.length; i++) { offset = r.id; segment = offset >> 12; v = core.wgetContent(host.tablename, offset, true); if (v !== undefined) { uts = ~~(v.uts.getTime() / 1000); v1 = (((v1 - offset) % 0xFFFFFF) + 0xFFFFFF) % 0xFFFFFF; v2 = (((v2 - uts) % 0xFFFFFF) + 0xFFFFFF) % 0xFFFFFF; v3 = (((v3 - offset*uts) % 0xFFFFFF) + 0xFFFFFF) % 0xFFFFFF; } host.segMark[segment] = true; uts = r[i].uts.getTime(); if (uts > lastuts) { lastuts = uts; lastid = offset; } else if ((uts == lastuts) && (offset > lastid)) { lastuts = uts; lastid = offset; } core.tables[host.tablename].data[offset] = r[i].data; uts = ~~(uts / 1000); v1 = (((v1 + offset) % 0xFFFFFF) + 0xFFFFFF) % 0xFFFFFF; v2 = (((v2 + uts) % 0xFFFFFF) + 0xFFFFFF) % 0xFFFFFF; v3 = (((v3 + offset*uts) % 0xFFFFFF) + 0xFFFFFF) % 0xFFFFFF; } break; case "block": for (i = 0; i < r.length; i++) { offset = r[i].id; segment = offset >> 12; v = core.wgetContent(host.tablename, offset, true); if (v !== undefined) { if (v.uts === undefined) { v = v; } uts = ~~(v.uts.getTime() / 1000); v1 = (((v1 - offset) % 0xFFFFFF) + 0xFFFFFF) % 0xFFFFFF; v2 = (((v2 - uts) % 0xFFFFFF) + 0xFFFFFF) % 0xFFFFFF; v3 = (((v3 - offset*uts) % 0xFFFFFF) + 0xFFFFFF) % 0xFFFFFF; } host.segMark[segment] = true; uts = r[i].uts.getTime(); if (uts > lastuts) { lastuts = uts; lastid = offset; } else if ((uts == lastuts) && (offset > lastid)) { lastuts = uts; lastid = offset; } uts = ~~(uts / 1000); v1 = (((v1 + offset) % 0xFFFFFF) + 0xFFFFFF) % 0xFFFFFF; v2 = (((v2 + uts) % 0xFFFFFF) + 0xFFFFFF) % 0xFFFFFF; v3 = (((v3 + offset*uts) % 0xFFFFFF) + 0xFFFFFF) % 0xFFFFFF; t = r[i].data; start = core.tables[host.tablename].data[offset]; if ((start === undefined) || (start == -1)) { core.tables[host.tablename].hostmodified[offset] = t; core.tables[host.tablename].data[offset] = -1; } else if (EncodingClass.number.fromArray("i32", core.tables[host.tablename].hostdata[segment], start) >= t.length) { for (j = 0; j < t.length; j++) { core.tables[host.tablename].hostdata[segment][start + j + 4] = t[j]; } k = EncodingClass.number.toArray("i32", t.length); for (j = 0; j < 4; j++) { core.tables[host.tablename].hostdata[segment][start + j] = k[j]; } if (core.tables[host.tablename].hostmodified[offset] !== undefined) delete core.tables[host.tablename].hostmodified[offset]; } else { core.tables[host.tablename].hostmodified[offset] = t; } } break; } if (index > host.lastindex) { host.lastindex = index; core.tables[host.tablename].config.lastuts = lastuts; core.tables[host.tablename].config.lastid = lastid; } c1 = (v1 + c1) % 0xFFFFFF; c2 = (v2 + c2) % 0xFFFFFF; c3 = (v3 + c3) % 0xFFFFFF; host.finished++; if (host.finished == host.total) { Thread.setTimeout({func: host.finalize}); } } } } (host); host.finalize = function (host) { return function () { core.tables[host.tablename].c1 = c1; core.tables[host.tablename].c2 = c2; core.tables[host.tablename].c3 = c3; Thread.setTimeout({ func: core.saveCache, args: [host.tablename, Object.keys(host.segMark), host.callbackfunc] }); } } (host); if (debugPrintFlag) console.log("fetchDataFromServer", tablename); if (core.tables[tablename] === undefined) throw new Error("Invalid tablename [" + tablename + "]"); if (core.tables[tablename].config === undefined) throw new Error("No config tablename [" + tablename + "]"); var pList = [ { name: "name", value: tablename }, { name: "lastid", value: core.tables[tablename].config.lastid }, { name: "lastuts", value: core.tables[tablename].config.lastuts } ]; if (core.tables[tablename].config.fieldList !== undefined) pList.push({ name: "fields", value: EncodingClass.string.fromVariable(core.tables[tablename].config.fieldList) }); core.apiqueue.push({ url: core.url, params: pList, func: function (host) { return function (success, contents) { var i, j, k; var segMark = {}, r, t, xf, v; var content, code, start, length; var segment, offset, uts, buf, keys, lastid; var tempqueue = []; if (!success) { if (debugPrintFlag) console.log("query failed, try again in 5s"); Thread.setTimeout({ func: core.fetchDataFromServer, args: [tablename, callbackfunc, c1, c2, c3], time: 5000 }); return; } for (k = 0; k < contents.length; k++) { code = contents[k].content[0]; switch (code) { case 0: // data tempqueue.push({ data: contents[k].content, callbackfunc: host.genCallbackFunc(k) }); host.total++; break; case 1: // deleted data host.deleted = []; start = 1; content = contents[k].content; while (start < content.length) { t = content[start++]; if (t == 0) { offset = EncodingClass.number.fromArray("i32", content, start); start += 4; segment = offset >> 12; if (core.tables[host.tablename].safemode !== true) { v = core.wgetContent(host.tablename, offset, true); if (v !== undefined) { uts = ~~(v.uts.getTime() / 1000); c1 = (((c1 - offset) % 0xFFFFFF) + 0xFFFFFF) % 0xFFFFFF; c2 = (((c2 - uts) % 0xFFFFFF) + 0xFFFFFF) % 0xFFFFFF; c3 = (((c3 - offset*uts) % 0xFFFFFF) + 0xFFFFFF) % 0xFFFFFF; } } switch (core.tables[host.tablename].mode) { case "block": if (core.tables[host.tablename].hostmodified[offset] !== undefined) { host.segMark[segment] = true; delete core.tables[host.tablename].hostmodified[offset]; } // intentionally omit break command - not syntax error case "row": if (core.tables[host.tablename].data[offset] !== undefined) { host.segMark[segment] = true; delete core.tables[host.tablename].data[offset]; } break; } } else { offset = EncodingClass.number.fromArray("i32", content, start); start += 4; length = EncodingClass.number.fromArray("i32", content, start); start += 4; for (j = 0; j < length; j++) { segment = offset >> 12; if (core.tables[host.tablename].safemode !== true) { v = core.wgetContent(host.tablename, offset, true); if (v !== undefined) { uts = ~~(v.uts.getTime() / 1000); c1 = (((c1 - offset) % 0xFFFFFF) + 0xFFFFFF) % 0xFFFFFF; c2 = (((c2 - uts) % 0xFFFFFF) + 0xFFFFFF) % 0xFFFFFF; c3 = (((c3 - offset*uts) % 0xFFFFFF) + 0xFFFFFF) % 0xFFFFFF; } } switch (core.tables[host.tablename].mode) { case "block": if (core.tables[host.tablename].hostmodified[offset] !== undefined) { host.segMark[segment] = true; delete core.tables[host.tablename].hostmodified[offset]; } // intentionally omit break command - not syntax error case "row": if (core.tables[host.tablename].data[offset] !== undefined) { host.segMark[segment] = true; delete core.tables[host.tablename].data[offset]; } break; } offset++; } } } break; case 2: // lastid content = contents[k].content; lastid = EncodingClass.number.fromArray("i32", content, 1); keys = Object.keys(core.tables[host.tablename].data); i = 0; Thread.exec( function () { if (i == keys.length) return true; offset = parseInt(keys[i++]); if (offset > lastid) { segment = offset >> 12; if (core.tables[host.tablename].safemode !== true) { v = core.wgetContent(host.tablename, offset, true); if (v !== undefined) { uts = ~~(v.uts.getTime() / 1000); c1 = (((c1 - offset) % 0xFFFFFF) + 0xFFFFFF) % 0xFFFFFF; c2 = (((c2 - uts) % 0xFFFFFF) + 0xFFFFFF) % 0xFFFFFF; c3 = (((c3 - offset*uts) % 0xFFFFFF) + 0xFFFFFF) % 0xFFFFFF; } } switch (core.tables[host.tablename].mode) { case "block": if (core.tables[host.tablename].hostmodified[offset] !== undefined) { host.segMark[segment] = true; delete core.tables[host.tablename].hostmodified[offset]; } // intentionally omit break command - not syntax error case "row": if (core.tables[host.tablename].data[offset] !== undefined) { host.segMark[segment] = true; delete core.tables[host.tablename].data[offset]; } break; } } return false; }, function () { keys = Object.keys(core.tables[host.tablename].hostmodified); i = 0; Thread.exec( function () { if (i == keys.length) { for (i = 0; i < tempqueue.length; i++) { core.decodequeue.push(tempqueue[i]); } tempqueue = null; if (host.total == 0) Thread.setTimeout({func: host.finalize}); return true; } offset = parseInt(keys[i++]); if (offset > lastid) { segment = offset >> 12; if (core.tables[host.tablename].safemode !== true) { v = core.wgetContent(host.tablename, offset, true); if (v !== undefined) { uts = ~~(v.uts.getTime() / 1000); c1 = (((c1 - offset) % 0xFFFFFF) + 0xFFFFFF) % 0xFFFFFF; c2 = (((c2 - uts) % 0xFFFFFF) + 0xFFFFFF) % 0xFFFFFF; c3 = (((c3 - offset*uts) % 0xFFFFFF) + 0xFFFFFF) % 0xFFFFFF; } } switch (core.tables[host.tablename].mode) { case "block": if (core.tables[host.tablename].hostmodified[offset] !== undefined) { host.segMark[segment] = true; delete core.tables[host.tablename].hostmodified[offset]; } // intentionally omit break command - not syntax error case "row": if (core.tables[host.tablename].data[offset] !== undefined) { host.segMark[segment] = true; delete core.tables[host.tablename].data[offset]; } break; } } return false; } ); } ); return; } } for (i = 0; i < tempqueue.length; i++) { core.decodequeue.push(tempqueue[i]); } tempqueue = null; if (host.total == 0) Thread.setTimeout({func: host.finalize}); } } (host) }); } } (core); core.decodeThread = function (core) { return function () { var instance; while ((core.decodequeue.length > 0) && (core.decodeWorkerCount < 8)) { instance = {}; if (debugPrintFlag) { instance.thread = function (me) { return { call: function (params) { var value = core.decodeFunc(params); me.thread.callbackfunc(value); }, callbackfunc: core.genCallbackRetvalFunc(me), terminate: function () { delete me.thread; } } } (instance); } else { instance.thread = Thread.createFromBlob({ blobURL: core.decodeBlob, callbackfunc: core.genCallbackRetvalFunc(instance) })[0]; } instance.exec = function (me) { return function () { var task = core.decodequeue.shift(); me.task = task.callbackfunc; me.thread.call( { content: task.data, size: task.data.length }, [task.data.buffer] ); } } (instance); instance.callbackfunc = function (me) { return function (retval) { Thread.setTimeout({ func: me.task, args: [retval] }); if (core.decodequeue.length > 0) { me.exec(); } else { me.thread.terminate(); core.decodeWorkerCount--; } } } (instance); instance.exec(); core.decodeWorkerCount++; } Thread.setTimeout({func: core.decodeThread}, 5); } } (core); Thread.setTimeout({func: core.decodeThread}, 5); core.writeCache = function (core) { return function (callbackfunc, path, list, transferList) { var rv = []; var writeThread = function () { if (list.length == 0) { Thread.setTimeout({ func: callbackfunc, args: [true, rv] }); return; } switch (fcore.workMode) { case "android": androidfs.writeFiles({ path: core.dbname + "_fsdb_" + path, list: [{ name: list[0].name, value: list[0].value }], callbackfunc: function (success, content) { rv.push(content[0]); list.shift(); Thread.setTimeout({ func: writeThread }); } }); break; case "idb": core.connectors[core.dbname].writeFile(path + "/" + list[0].name, list[0].value, function () { rv.push({ name: list[0].name, success: true, content: list[0].value.length }); list.shift(); Thread.setTimeout({ func: writeThread }); }); break; } } switch (fcore.workMode) { case "fsapi": fs.writeFiles({ path: core.dbname + "_fsdb_" + path, list: list, transferList: transferList, callbackfunc: callbackfunc }); break; case "android": case "idb": transferList = null; Thread.setTimeout({ func: writeThread }); break; } } } (core); core.prepareSaveDataThreads = Thread.createWorkerPool({ extcode: EncodingClass.exportCode(), func: function (params) { var dbver = params.dbver; var mode = params.mode; var xkey = params.xkey; var hostdata = params.hostdata; var data = params.data; var v, xv, ts, ti; var i, k, offset, old, xlen = 5; transferList = []; if (mode == "row") { for (i = 0; i < data.length; i++) { offset = data[i][0]; xlen += data[i][1].length; } v = null; xv = new Uint8Array(xlen); EncodingClass.number.writeArray("i16", dbver, xv, 3); xlen = 5; for (i = 0; i < data.length; i++) { offset = data[i][0]; EncodingClass.number.writeArray("i32", offset, xv, xlen); xlen += 4; EncodingClass.number.writeArray("i32", data[i][1].length - 8, xv, xlen); xlen += 4; for (j = 0; j < data[i][1].length; j++) { xv[xlen++] = data[i][1][j]; } transferList.push(data[i][1]); } } else { for (i = k = 0; i < data.length; i++) { if (data[i][1] !== -1) data[k++] = data[i]; } data.length = k; for (i = 0; i < data.length; i++) { if (EncodingClass.type.isNumber(data[i][1])) { l = EncodingClass.number.fromArray("i32", hostdata, data[i][1]) + 8; } else { l = data[i][1].length; } xlen += l + 8; } v = new Uint8Array(xlen); EncodingClass.number.writeArray("i16", dbver, v, 3); xlen = 5; for (i = 0; i < data.length; i++) { offset = data[i][0]; if (EncodingClass.type.isNumber(data[i][1])) { EncodingClass.number.writeArray("i32", offset, v, xlen); xlen += 4; start = data[i][1]; data[i][1] = xlen; l = EncodingClass.number.fromArray("i32", hostdata, start) + 12; for (j = 0; j < l; j++) { v[xlen++] = hostdata[start + j]; } } else { EncodingClass.number.writeArray("i32", offset, v, xlen); xlen += 4; old = data[i][1]; data[i][1] = xlen; l = old.length; EncodingClass.number.writeArray("i32", l - 8, v, xlen); xlen += 4; for (j = 0; j < l; j++) { v[xlen++] = old[j]; } } } transferList.push(v.buffer); xv = new Uint8Array(v.length); xv.set(v); } transferList.push(xv.buffer); ts = EncodingClass.number.rndFunc(0x9E3779B9, 0x243F6A88, 0xB7E15162, xkey); ti = EncodingClass.number.toArray("i32", xkey); for (i = 0; i < 3; i++) xv[i] = ti[i]; for (i = 3; i < xv.length; i++) xv[i] ^= ts(256); return { hostdata: v, data: data, saveData: xv } } }); core.getChecksum = function (core) { return function (tablename, callbackfunc) { var calldata = { url: core.url, params: [ { name: "name", value: tablename }, { name: "lastid", value: 0 }, { name: "lastuts", value: 0 }, { name: "task", value: "chksum" } ], func: function (success, message) { if (success) { if (message.substr(0, 2) == "ok") { Thread.setTimeout({ func: callbackfunc, args: [message.substr(2)] }); } else { if (debugPrintFlag) console.log("request run-time error", message); } } else { if (debugPrintFlag) console.log("request error, try again in 5s"); Thread.setTimeout({ func: core.getChecksum, args: [tablename, callbackfunc] }); } } }; if (core.calldataFunc !== undefined) core.calldataFunc(calldata); FormClass.api_call(calldata); } } (core); core.remove = function (core) { return function (tablename, callbackfunc) { switch (fcore.workMode) { case "android": androidfs.remove(core.dbname + "_fsdb_" + tablename, function (success) { Thread.setTimeout({ func: callbackfunc, args: [success] }); }); break; case "fsapi": fs.remove(function (success) { Thread.setTimeout({ func: callbackfunc, args: [success] }); }, core.dbname + "_fsdb_" + tablename); break; case "idb": core.connectors[core.dbname].remove(tablename, function () { callbackfunc(); }); break; } } } (core); core.saveCacheThread = function (core) { return function (host) { var transferList = []; var segno, xkey, fs, ts; var i, j, k, v, t, p, l, xv, ti, xlen, start; var data, hostdata, transferList; for (k = 0; k < host.segList.length; k++) { segno = parseInt(host.segList[k]); fs = segno << 12; ts = fs + 4096; data = []; transferList = []; if (core.tables[host.tablename].mode == "row") { for (i = fs; i < ts; i++) { if (core.tables[host.tablename].data[i] !== undefined) { data.push([i, core.tables[host.tablename].data[i]]); if (core.tables[host.tablename].safemode !== true) transferList.push(core.tables[host.tablename].data[i].buffer); } } hostdata = null; } else { if (core.tables[host.tablename].hostdata[segno] !== undefined) { hostdata = core.tables[host.tablename].hostdata[segno]; if (core.tables[host.tablename].safemode !== true) transferList.push(hostdata.buffer); } else { hostdata = null; } for (i = fs; i < ts; i++) { if (core.tables[host.tablename].hostmodified[i] !== undefined) { data.push([i, core.tables[host.tablename].hostmodified[i]]); if (core.tables[host.tablename].safemode !== true) transferList.push(core.tables[host.tablename].hostmodified[i].buffer); } else if (core.tables[host.tablename].data[i] !== undefined) { data.push([i, core.tables[host.tablename].data[i]]); } } } xkey = (core.mainRnd(0xFFFFFFF) + segno * 1001 + 11) & 0xFFFFFF; core.prepareSaveDataThreads.call({ params: { mode: core.tables[host.tablename].mode, dbver: dbver, xkey: xkey, hostdata: hostdata, data: data }, transferList: transferList, callbackfunc: function (host, segno, index) { return function (retval) { var i, offset, transferList; if (core.tables[host.tablename] === undefined) return; if (core.tables[host.tablename].hostdata === undefined) core.tables[host.tablename].hostdata = []; if (retval.hostdata !== null) core.tables[host.tablename].hostdata[segno] = retval.hostdata; for (i = 0; i < retval.data.length; i++) { offset = retval.data[i][0]; core.tables[host.tablename].data[offset] = retval.data[i][1]; if (core.tables[host.tablename].mode == "block") { if (core.tables[host.tablename].hostmodified[offset] !== undefined) delete core.tables[host.tablename].hostmodified[offset]; } } host.queue[index] = { name: "s" + segno, value: retval.saveData } host.finished++; if (host.finished == host.total) { transferList = []; for (i = 0; i < host.queue.length; i++) { if (!EncodingClass.type.isString(host.queue[i].value)) { transferList.push(host.queue[i].value.buffer); } } if (core.tables[host.tablename].safemode !== true) { core.getChecksum(host.tablename, function (chksum) { if (chksum == EncodingClass.md5.encode(core.tables[host.tablename].c1 + "/" + core.tables[host.tablename].c2 + "/" + core.tables[host.tablename].c3)) { if (debugPrintFlag) console.log("checksum ok", host.tablename); core.writeCache(function () { if (debugPrintFlag) console.log("saveCache done", host.tablename); core.tables[host.tablename].safemode = true; Thread.setTimeout({ func: host.callbackfunc, args: [true] }); }, host.tablename, host.queue, transferList); } else { if (debugPrintFlag) console.log("checksum error", host.tablename); host.mode = core.tables[host.tablename].mode; fcore.resetTable(core, host.tablename, host.callbackfunc); } }); } else { core.writeCache(function () { if (debugPrintFlag) console.log("saveCache done 1", host.tablename); core.tables[host.tablename].safemode = true; Thread.setTimeout({ func: host.callbackfunc, args: [true] }); }, host.tablename, host.queue, transferList); } } } } (host, segno, k) }); host.queue.push(null); } core.tables[host.tablename].config.chksum = EncodingClass.md5.encode(EncodingClass.string.fromVariable({ lastid: core.tables[host.tablename].config.lastid, lastuts: core.tables[host.tablename].config.lastuts, format: core.tables[host.tablename].config.format }) + "_" + core.dbname + "_" + dbver); host.queue.push({ name: "config", value: EncodingClass.number.fromVariable(core.tables[host.tablename].config) }); if (core.tables[host.tablename].safemode !== true) { if (core.tables[host.tablename].mode == "block") core.tables[host.tablename].hostmodified = []; } } } (core); core.saveCache = function (core) { return function (tablename, segList, callbackfunc) { if (debugPrintFlag) console.log("saveCache", tablename); var host = { tablename: tablename, segList: segList, total: segList.length, queue: [], finished: 0, callbackfunc: callbackfunc }; var i; if (host.total > 0) { Thread.setTimeout({ func: core.saveCacheThread, args: [host] }); } else { core.tables[tablename].config.chksum = EncodingClass.md5.encode(EncodingClass.string.fromVariable({ lastid: core.tables[tablename].config.lastid, lastuts: core.tables[tablename].config.lastuts, format: core.tables[tablename].config.format }) + "_" + core.dbname + "_" + dbver); if (core.tables[host.tablename].safemode !== true) { core.getChecksum(host.tablename, function (chksum) { //if (chksum == core.tables[host.tablename].c1 + "/" + core.tables[host.tablename].c2 + "/" + core.tables[host.tablename].c3) { if (chksum == EncodingClass.md5.encode(core.tables[host.tablename].c1 + "/" + core.tables[host.tablename].c2 + "/" + core.tables[host.tablename].c3)) { if (debugPrintFlag) console.log("checksum ok", host.tablename); core.writeCache(function () { if (debugPrintFlag) console.log("saveCache done 2", tablename); core.tables[host.tablename].safemode = true; Thread.setTimeout({ func: callbackfunc, args: [true] }); }, tablename, [{name: "config", value: EncodingClass.number.fromVariable(core.tables[tablename].config)}]); } else { if (debugPrintFlag) console.log("checksum error", host.tablename); host.mode = core.tables[host.tablename].mode; fcore.resetTable(core, host.tablename, host.callbackfunc); } }); return; } core.writeCache(function () { if (debugPrintFlag) console.log("saveCache done", tablename); core.tables[host.tablename].safemode = true; Thread.setTimeout({ func: callbackfunc, args: [true] }); }, tablename, [{name: "config", value: EncodingClass.number.fromVariable(core.tables[tablename].config)}]); } } } (core); core.wgetContent = function (core) { return function (tablename, id, keeputs) { var segno; if (core.tables[tablename] === undefined) return undefined; if (core.tables[tablename].config.format === undefined) return undefined; switch (core.tables[tablename].mode) { case "row": if (core.tables[tablename].data[id] === undefined) return undefined; break; case "block": if ((core.tables[tablename].data[id] === undefined) && (core.tables[tablename].hostmodified[id] === undefined)) return undefined; segno = id >> 12; if (core.tables[tablename].hostdata[segno] === undefined) return undefined; break; } return core.getContent(tablename, id, keeputs); } } (core); core.wgetContent2 = function (core) { return function (tablename, ids, keeputs, callbackfunc) { var r = []; if (core.tables[tablename] === undefined) { Thread.setTimeout({func: callbackfunc}); return; } if (ids.length == 0) { Thread.setTimeout({ func: callbackfunc, args: [[]] }); return; } if (core.tables[tablename].config.format === undefined) { Thread.setTimeout({func: callbackfunc}); return; } var index = 0, imax = 10; var readThread = function () { var stime = (new Date()).getTime(); var i, id, ilen; var xtime = stime, ttime; while (index < ids.length) { ilen = ids.length - index; if (ilen > imax) ilen = imax; for (i = 0; i < ilen; i++) { id = ids[index++]; switch (core.tables[tablename].mode) { case "row": if (core.tables[tablename].data[id] === undefined) continue; break; case "block": if ((core.tables[tablename].data[id] === undefined) && (core.tables[tablename].hostmodified[id] === undefined)) continue; break; } r.push(core.getContent(tablename, id, keeputs)); } ttime = (new Date()).getTime(); if (ttime - stime > 40) break; if (ttime - xtime < 5) { imax = ~~(imax * 1.1); } else { imax = ~~(imax * 0.9); if (imax < 10) imax = 10; } xtime = ttime; } if (index == ids.length) { Thread.setTimeout({ func: callbackfunc, args: [r] }); } else { Thread.setTimeout({func: readThread}); } } Thread.setTimeout({func: readThread}); } } (core); core.getContent = function (core) { return function (tablename, id, keeputs) { var segno, v, start, length; switch (core.tables[tablename].mode) { case "row": v = EncodingClass.string.fromUint8Array(core.tables[tablename].data[id], 8); break; case "block": segno = id >> 12; if (core.tables[tablename].hostmodified[id] !== undefined) { v = EncodingClass.string.fromUint8Array(core.tables[tablename].hostmodified[id], 8); } else { start = core.tables[tablename].data[id]; length = EncodingClass.number.fromArray("i32", core.tables[tablename].hostdata[segno], start); v = EncodingClass.string.fromUint8Array(core.tables[tablename].hostdata[segno], start + 12, length); } break; default: return undefined; } v = EncodingClass.number.toStructRecord(core.tables[tablename].config.format, v); if (keeputs !== true) { delete v.uts; } else { if (core.tables[tablename].hostmodified[id] !== undefined) { v.uts = new Date(EncodingClass.number.fromArray("f64", core.tables[tablename].hostmodified[id])); } else { v.uts = new Date(EncodingClass.number.fromArray("f64", core.tables[tablename].hostdata[segno], start + 4)); } } return v; } } (core); core.getInstance = function (core) { return function (tablename) { var r = {}; r.exists = function (id) { if (core.tables[tablename] === undefined) return false; return core.tables[tablename].data[id] !== undefined; }; r.getIDList = function (callbackfunc) { return core.getIDList(tablename, callbackfunc); }; r.read = function (id) { return core.wgetContent(tablename, id); }; r.reads = function (ids, callbackfunc) { return core.wgetContent2(tablename, ids, false, callbackfunc); }; r.promiseReads = function (ids) { return new Promise(function(resolve, reject) { core.wgetContent2(tablename, ids, false, function (values) { resolve(values); }); }); }; r.load = function (callbackfunc) { core.tables[tablename].safemode = true; Thread.setTimeout({ func: core.fetchDataFromServer, args: [tablename, callbackfunc, 0, 0, 0] }); }; r.promiseLoad = function () { var host = {}; Thread.setTimeout({ func: r.load, args: [function () { Thread.setTimeout({func: host.resolve}); }] }); return new Promise(function(resolve, reject) { host.resolve = resolve; host.reject = reject; }); }; r.reset = function (callbackfunc) { fcore.resetTable(core, tablename, function () { Thread.setTimeout({ func: core.fetchDataFromServer, args: [tablename, callbackfunc, 0, 0, 0] }); }); } r.promiseReset = function () { var host = {}; Thread.setTimeout({ func: r.reset, args: [function () { Thread.setTimeout({func: host.resolve}); }] }); return new Promise(function(resolve, reject) { host.resolve = resolve; host.reject = reject; }); } r.search = function (searchFunc, callbackfunc) { return core.search(tablename, searchFunc, callbackfunc); }; r.psearch = function (params) { var nthread, searchFunc, extraParams, callbackfunc; nthread = params.nthread; searchFunc = params.searchFunc; extraParams = params.extraParams; callbackfunc = params.callbackfunc; postFunc = params.postFunc; if (nthread === undefined) nthread = navigator.hardwareConcurrency; if (callbackfunc === undefined) return; if (!EncodingClass.type.isFunction(callbackfunc)) return; if (searchFunc === undefined) return; if (!EncodingClass.type.isFunction(searchFunc)) return; if (postFunc !== undefined) if (!EncodingClass.type.isFunction(postFunc)) postFunc = undefined; core.psearch(tablename, nthread, searchFunc, postFunc, callbackfunc, extraParams); }; r.promiseSearch = function (me) { return function (params) { return new Promise(function(resolve, reject) { me.psearch({ nthread: params.nthread, searchFunc: params.searchFunc, extraParams: params.extraParams, postFunc: params.postFunc, callbackfunc: function (retval) { resolve(retval); } }); }); } } (r); return r; } } (core); core.load = function (core) { return function (tablename, mode, callbackfunc, options) { if (core.inited[tablename] === undefined) { core.init(tablename, mode, function (success) { if (success) { core.inited[tablename] = true; core.tables[tablename].instance = core.getInstance(tablename); Thread.setTimeout({ func: callbackfunc, args: [core.tables[tablename].instance] }); } else { Thread.setTimeout({ func: callbackfunc, args: [] }); } }, options); return; } if (core.inited[tablename] === null) { Thread.wait( function (tablename) { return function () { return (core.inited[tablename] !== null) && (core.inited[tablename] !== undefined); } } (tablename), function (callbackfunc, tablename) { return function () { Thread.setTimeout({ func: callbackfunc, args: [core.tables[tablename].instance] }); } } (callbackfunc, tablename) ); return; } Thread.setTimeout({ func: callbackfunc, args: [core.tables[tablename].instance] }); } } (core); core.promiseLoad = function (core) { return function (tablename, mode, options) { return new Promise(function(resolve, reject) { core.load(tablename, mode, function (result) { Thread.setTimeout({ func: resolve, args: [result] }); }, options); }); } } (core); core.searchblob = Thread.generateBlob({ extcode: "var searchFunc, extraParams, format, mode, window = {};\r\n" + EncodingClass.exportCode(), func: function (params) { var task, content, segno, ffsets, id, fs; var i, j, r, v, xv; var slen, tdata, tlength; task = params[0]; content = params[1]; switch (task) { case "func": r = EncodingClass.pack.fromUint8Array(content.searchFunc); r = r.read(); searchFunc = r.searchFunc; extraParams = r.extraParams; r = null; format = content.format; mode = content.mode; return true; case "search": r = []; switch (mode) { case "row": for (i = 0; i < content.data.length; i++) { v = EncodingClass.string.fromUint8Array(content.data[i]); v = EncodingClass.number.toStructRecord(format, v); delete v.uts; try { v = searchFunc(v); if (v !== null) r.push(v); } catch (e) { } } break; case "block": for (i = 0; i < content.data.length; i++) { v = content.data[i]; if (EncodingClass.type.isNumber(v)) { length = EncodingClass.number.fromArray("i32", content.hostdata, v); v = EncodingClass.string.fromUint8Array(content.hostdata, v + 12, length); } else { v = EncodingClass.string.fromUint8Array(v); } v = EncodingClass.number.toStructRecord(format, v); delete v.uts; try { v = searchFunc(v); if (v !== null) r.push(v); } catch (e) { } } break; } v = EncodingClass.pack.fromVariable(r); r = v.toUint8Array(); v.terminate(); transferList = [r.buffer]; return r; case "clear": searchFunc = null; extraParams = null; format = null; mode = null; return true; } } }); core.genCallbackRetvalFunc = function (me) { return function (retval) { Thread.setTimeout({ func: me.callbackfunc, args: [retval] }); } }; core.psearch = function (core) { return function (tablename, nthread, searchFunc, postFunc, callbackfunc, extraParams) { var host = { postFunc: postFunc, threads: [], segLists: [], segKeys: [], nthread: nthread, segMark: [], waiting: 0 }; var segno; var keys, table; var i, t, v; if (searchFunc === undefined) return; if (core.tables[tablename] === undefined) { Thread.setTimeout({ func: callbackfunc, args: [[]] }); return; }; table = core.tables[tablename].data; keys = Object.keys(table); if (keys.length == 0) { Thread.setTimeout({ func: callbackfunc, args: [[]] }); return; } t = EncodingClass.pack.fromVariable({ searchFunc: searchFunc, extraParams: extraParams }); host.searchFunc = t.toUint8Array(); t.terminate(); for (i = 0; i < keys.length; i++) { segno = parseInt(keys[i]) >> 12; if (host.segMark[segno] === undefined) { host.segMark[segno] = true; host.segLists.push(segno); } } keys = null; host.segLists.sort((a, b) => (b - a)); for (i = 0; i < host.segLists.length; i++) { host.segKeys.push(host.segLists[i]); } if (nthread > navigator.hardwareConcurrency * 2) nthread = navigator.hardwareConcurrency * 2; while (host.threads.length < nthread) { t = {}; t.instance = Thread.createFromBlob({ blobURL: core.searchblob, callbackfunc: core.genCallbackRetvalFunc(t) })[0]; host.threads.push(t); } host.receiveThread = function (host) { return function (vhost) { vhost.r = EncodingClass.pack.fromUint8Array(vhost.r); vhost.r.read([], function (r) { var i, k, v; if (host.postFunc !== undefined) { for (i = k = 0; i < r.length; i++) { try { v = host.postFunc(r[i]); if (v !== null) r[k++] = v; } catch (e) { console.log("postFunc error", e); } } while (r.length > k) r.pop(); } host.segMark[vhost.segno] = r; vhost.r.terminate(); delete vhost.r; delete vhost.segno; host.waiting--; }); } } (host); host.search = function (host) { return function (thread, segno) { var i, t, fs, ts, content = {data: [], segno: segno}; var transferList = []; thread.callbackfunc = function (retval) { vhost = { segno: segno, r: retval }; host.waiting++; Thread.setTimeout({ func: host.workingThread, args: [thread], priority: 9 }); Thread.setTimeout({ func: host.receiveThread, args: [vhost] }); } fs = segno << 12; ts = (segno + 1) << 12; switch (core.tables[tablename].mode) { case "row": for (i = fs; i < ts; i++) { if (core.tables[tablename].data[i] !== undefined) { t = new Uint8Array(core.tables[tablename].data[i]); content.data.push(t); transferList.push(t.buffer); } } break; case "block": t = new Uint8Array(core.tables[tablename].hostdata[segno]); content.hostdata = t; transferList.push(t.buffer); for (i = fs; i < ts; i++) { if (core.tables[tablename].data[i] !== undefined) { if (core.tables[tablename].hostmodified[i] !== undefined) { t = new Uint8Array(core.tables[tablename].hostmodified[i]); transferList.push(t.buffer); content.data.push(t); } else { content.data.push(core.tables[tablename].data[i]); } } } break; } thread.instance.call(["search", content], transferList); } } (host); host.workingThread = function (host) { return function (thread) { if (host.segLists.length > 0) { if (thread === undefined) { if (host.threads.length > 0) { thread = host.threads.pop(); thread.callbackfunc = function () { Thread.setTimeout({ func: host.workingThread, args: [thread] }); } EncodingClass.number.duplicateTypedArray(host.searchFunc, function (fdata) { thread.instance.call(["func", { searchFunc: fdata, format: core.tables[tablename].config.format, mode: core.tables[tablename].mode }], [fdata.buffer]); }); } return; } host.search(thread, host.segLists.pop()); return; } if (thread !== undefined) { thread.callbackfunc = function () { delete thread.callbackfunc; host.threads.push(thread); if (host.threads.length == host.nthread) { while (host.threads.length > 0) host.threads.pop().instance.terminate(); Thread.wait( function () { return host.waiting == 0; }, function () { var i, r, segno; r = []; while (host.segKeys.length > 0) { segno = host.segKeys.pop(); for (i = 0; i < host.segMark[segno].length; i++) { r.push(host.segMark[segno][i]); } } Thread.setTimeout({ func: callbackfunc, args: [r] }); } ); } } thread.instance.call(["clear"]); } } } (host); while ((host.segLists.length > 0) && (host.threads.length > 0)) host.workingThread(); } } (core); core.getIDList = function (core) { return function (tablename, callbackfunc) { var keys, i; if (core.tables[tablename] === undefined) { if (callbackfunc !== undefined) { Thread.setTimeout({ func: callbackfunc, args: [[]] }); } return []; } keys = Object.keys(core.tables[tablename].data); if (callbackfunc === undefined) { for (i = 0; i < keys.length; i++) { keys[i] = parseInt(keys[i]); } keys.sort((a, b) => (a - b)); return keys; } i = 0; Thread.exec( function () { if (i >= keys.length) return true; keys[i] = parseInt(keys[i]); i++; return false; }, function () { EncodingClass.number.asyncSort(keys, (a, b) => (a - b), function () { callbackfunc(keys); }); } ); } } (core); core.backgroundSearch = function (core) { return function (tablename, searchFunc, callbackfunc) { var keys, r = [], index = 0; var searchThread = function () { var time = (new Date()).getTime(); var v, t, i, ilen; while (index < keys.length) { ilen = keys.length - index; if (ilen > 1024) ilen = 1024; for (i = 0; i < ilen; i++) { t = core.getContent(tablename, keys[index++]); try { v = searchFunc(t); if (v !== null) r.push(v); } catch (e) { } } if ((new Date()).getTime() - time > 40) break; } if (index == keys.length) { if (EncodingClass.type.isFunction(callbackfunc)) { Thread.setTimeout({ func: callbackfunc, args: [r] }); } return; } Thread.setTimeout({func: searchThread}); } keys = core.getIDList(tablename); Thread.setTimeout({func: searchThread}); } } (core); core.search = function (core) { return function (tablename, searchFunc, callbackfunc) { var r = [], keys; var i, t, v; if (core.tables[tablename] === undefined) { if (callbackfunc !== undefined) { callbackfunc([]); return false; } return []; } if (callbackfunc === undefined) { keys = core.getIDList(tablename); for (i = 0; i < keys.length; i++) { t = core.getContent(tablename, keys[i]); try { v = searchFunc(t); if (v !== null) r.push(v); } catch (e) { } } return r; } else { Thread.setTimeout({ func: core.backgroundSearch, args: [tablename, searchFunc, callbackfunc] }); return true; } } } (core); retval.load = function (core) { return function (tablename, mode, callbackfunc, fieldList) { if (mode === undefined) mode = "block"; mode = mode.toLowerCase(); if ((mode != "row") && (mode != "block")) mode = "block"; core.load(tablename, mode, callbackfunc, fieldList); } } (core); retval.promiseLoad = function (core) { return function (tablename, mode, fieldList) { return core.promiseLoad(tablename, mode, fieldList); } } (core); retval.erase = function (core) { return function (tablename, callbackfunc) { core.remove(tablename, function (success) { delete core.tables[tablename]; if (debugPrintFlag) console.log("erase table " + tablename, success); Thread.setTimeout({func: callbackfunc}); }); } } (core); retval.eraseAll = function (core) { return function (callbackfunc) { var keys; var i; var count = 0; keys = Object.keys(core.tables); for (i = 0; i < keys.length; i++) { retval.erase(keys[i], function () { count++; if (count == keys.length) Thread.setTimeout({func: callbackfunc}); }); } } } (core); Object.defineProperty(retval, "url", { get: function () { return core.url; }, set: function (value) { core.url = value; } }); if (false) { delete retval.erase; delete retval.eraseAll; } return retval; } return Object.freeze(fcache_retval); } ());