1fb726d48Sopenharmony_ci/* 2fb726d48Sopenharmony_ci * Copyright (C) 2022 Huawei Device Co., Ltd. 3fb726d48Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4fb726d48Sopenharmony_ci * you may not use this file except in compliance with the License. 5fb726d48Sopenharmony_ci * You may obtain a copy of the License at 6fb726d48Sopenharmony_ci * 7fb726d48Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8fb726d48Sopenharmony_ci * 9fb726d48Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10fb726d48Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11fb726d48Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12fb726d48Sopenharmony_ci * See the License for the specific language governing permissions and 13fb726d48Sopenharmony_ci * limitations under the License. 14fb726d48Sopenharmony_ci */ 15fb726d48Sopenharmony_ci 16fb726d48Sopenharmony_ciclass DbThread { 17fb726d48Sopenharmony_ci busy: boolean = false; 18fb726d48Sopenharmony_ci id: number = -1; 19fb726d48Sopenharmony_ci //@ts-ignore 20fb726d48Sopenharmony_ci taskMap: unknow = {}; 21fb726d48Sopenharmony_ci worker?: Worker; 22fb726d48Sopenharmony_ci traceId: string; 23fb726d48Sopenharmony_ci 24fb726d48Sopenharmony_ci constructor(worker: Worker, traceId: string) { 25fb726d48Sopenharmony_ci this.worker = worker; 26fb726d48Sopenharmony_ci this.traceId = traceId; 27fb726d48Sopenharmony_ci } 28fb726d48Sopenharmony_ci 29fb726d48Sopenharmony_ci uuid(): string { 30fb726d48Sopenharmony_ci // @ts-ignore 31fb726d48Sopenharmony_ci return ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, (c: unknow) => 32fb726d48Sopenharmony_ci (c ^ (crypto.getRandomValues(new Uint8Array(1))[0] & (15 >> (c / 4)))).toString(16) 33fb726d48Sopenharmony_ci ); 34fb726d48Sopenharmony_ci } 35fb726d48Sopenharmony_ci 36fb726d48Sopenharmony_ci //@ts-ignore 37fb726d48Sopenharmony_ci queryFunc(name: string, sql: string, args: unknow, handler: Function, action: string | null): void { 38fb726d48Sopenharmony_ci this.busy = true; 39fb726d48Sopenharmony_ci let id = this.uuid(); 40fb726d48Sopenharmony_ci this.taskMap[id] = handler; 41fb726d48Sopenharmony_ci let msg = { 42fb726d48Sopenharmony_ci id: id, 43fb726d48Sopenharmony_ci name: name, 44fb726d48Sopenharmony_ci action: action || 'exec', 45fb726d48Sopenharmony_ci sql: sql, 46fb726d48Sopenharmony_ci params: args, 47fb726d48Sopenharmony_ci }; 48fb726d48Sopenharmony_ci this.worker?.postMessage(msg); 49fb726d48Sopenharmony_ci } 50fb726d48Sopenharmony_ci 51fb726d48Sopenharmony_ci //@ts-ignore 52fb726d48Sopenharmony_ci queryProto(name: number, args: unknow, handler: Function): void { 53fb726d48Sopenharmony_ci this.busy = true; 54fb726d48Sopenharmony_ci let id = this.uuid(); 55fb726d48Sopenharmony_ci this.taskMap[id] = handler; 56fb726d48Sopenharmony_ci let msg = { 57fb726d48Sopenharmony_ci id: id, 58fb726d48Sopenharmony_ci name: name, 59fb726d48Sopenharmony_ci action: 'exec-proto', 60fb726d48Sopenharmony_ci params: args, 61fb726d48Sopenharmony_ci }; 62fb726d48Sopenharmony_ci this.worker?.postMessage(msg); 63fb726d48Sopenharmony_ci } 64fb726d48Sopenharmony_ci 65fb726d48Sopenharmony_ci cutFileByRange( 66fb726d48Sopenharmony_ci leftTs: number, 67fb726d48Sopenharmony_ci rightTs: number, 68fb726d48Sopenharmony_ci handler: (status: boolean, msg: string, splitBuffer?: ArrayBuffer) => void 69fb726d48Sopenharmony_ci ): void { 70fb726d48Sopenharmony_ci this.busy = true; 71fb726d48Sopenharmony_ci let id = this.uuid(); 72fb726d48Sopenharmony_ci //@ts-ignore 73fb726d48Sopenharmony_ci this.taskMap[id] = (res: unknow): void => { 74fb726d48Sopenharmony_ci setThreadPoolTraceBuffer(this.traceId, res.buffer); 75fb726d48Sopenharmony_ci if (res.cutStatus) { 76fb726d48Sopenharmony_ci handler(res.cutStatus, res.msg, res.cutBuffer); 77fb726d48Sopenharmony_ci } else { 78fb726d48Sopenharmony_ci handler(res.cutStatus, res.msg); 79fb726d48Sopenharmony_ci } 80fb726d48Sopenharmony_ci }; 81fb726d48Sopenharmony_ci caches.match(getThreadPoolTraceBufferCacheKey(this.traceId)).then((resData) => { 82fb726d48Sopenharmony_ci if (resData) { 83fb726d48Sopenharmony_ci resData.arrayBuffer().then((buffer) => { 84fb726d48Sopenharmony_ci this.worker!.postMessage( 85fb726d48Sopenharmony_ci { 86fb726d48Sopenharmony_ci id: id, 87fb726d48Sopenharmony_ci action: 'cut-file', 88fb726d48Sopenharmony_ci leftTs: leftTs, 89fb726d48Sopenharmony_ci rightTs: rightTs, 90fb726d48Sopenharmony_ci buffer: buffer!, 91fb726d48Sopenharmony_ci }, 92fb726d48Sopenharmony_ci [buffer!] 93fb726d48Sopenharmony_ci ); 94fb726d48Sopenharmony_ci }); 95fb726d48Sopenharmony_ci } 96fb726d48Sopenharmony_ci }); 97fb726d48Sopenharmony_ci } 98fb726d48Sopenharmony_ci 99fb726d48Sopenharmony_ci dbOpen = async ( 100fb726d48Sopenharmony_ci parseConfig: string, 101fb726d48Sopenharmony_ci sdkWasmConfig?: string, 102fb726d48Sopenharmony_ci buffer?: ArrayBuffer 103fb726d48Sopenharmony_ci ): Promise<{ 104fb726d48Sopenharmony_ci status: boolean; 105fb726d48Sopenharmony_ci msg: string; 106fb726d48Sopenharmony_ci buffer: ArrayBuffer; 107fb726d48Sopenharmony_ci //@ts-ignore 108fb726d48Sopenharmony_ci sdkConfigMap: unknow; 109fb726d48Sopenharmony_ci fileKey: string; 110fb726d48Sopenharmony_ci }> => { 111fb726d48Sopenharmony_ci //@ts-ignore 112fb726d48Sopenharmony_ci return new Promise<unknow>((resolve, reject) => { 113fb726d48Sopenharmony_ci let id = this.uuid(); 114fb726d48Sopenharmony_ci //@ts-ignore 115fb726d48Sopenharmony_ci this.taskMap[id] = (res: unknow): unknow => { 116fb726d48Sopenharmony_ci if (res.init) { 117fb726d48Sopenharmony_ci resolve({ 118fb726d48Sopenharmony_ci status: res.init, 119fb726d48Sopenharmony_ci msg: res.msg, 120fb726d48Sopenharmony_ci sdkConfigMap: res.configSqlMap, 121fb726d48Sopenharmony_ci buffer: res.buffer, 122fb726d48Sopenharmony_ci fileKey: res.fileKey, 123fb726d48Sopenharmony_ci }); 124fb726d48Sopenharmony_ci } else { 125fb726d48Sopenharmony_ci resolve({ status: res.init, msg: res.msg }); 126fb726d48Sopenharmony_ci } 127fb726d48Sopenharmony_ci }; 128fb726d48Sopenharmony_ci this.worker?.postMessage( 129fb726d48Sopenharmony_ci { 130fb726d48Sopenharmony_ci id: id, 131fb726d48Sopenharmony_ci action: 'open', 132fb726d48Sopenharmony_ci parseConfig: parseConfig, 133fb726d48Sopenharmony_ci wasmConfig: sdkWasmConfig, 134fb726d48Sopenharmony_ci buffer: buffer! /*Optional. An ArrayBuffer representing an SQLite Database file*/, 135fb726d48Sopenharmony_ci }, 136fb726d48Sopenharmony_ci [buffer!] 137fb726d48Sopenharmony_ci ); 138fb726d48Sopenharmony_ci }); 139fb726d48Sopenharmony_ci }; 140fb726d48Sopenharmony_ci 141fb726d48Sopenharmony_ci resetWASM(): void { 142fb726d48Sopenharmony_ci this.worker?.postMessage({ 143fb726d48Sopenharmony_ci id: this.uuid(), 144fb726d48Sopenharmony_ci action: 'reset', 145fb726d48Sopenharmony_ci }); 146fb726d48Sopenharmony_ci } 147fb726d48Sopenharmony_ci} 148fb726d48Sopenharmony_ci 149fb726d48Sopenharmony_ciexport class DbPool { 150fb726d48Sopenharmony_ci sharedBuffer: ArrayBuffer | null = null; 151fb726d48Sopenharmony_ci fileCacheKey: string = 'null'; 152fb726d48Sopenharmony_ci traceId: string; 153fb726d48Sopenharmony_ci maxThreadNumber: number = 0; 154fb726d48Sopenharmony_ci works: Array<DbThread> = []; 155fb726d48Sopenharmony_ci progress: Function | undefined | null; 156fb726d48Sopenharmony_ci num = Math.floor(Math.random() * 10 + 1) + 20; 157fb726d48Sopenharmony_ci cutDownTimer: unknown | undefined; 158fb726d48Sopenharmony_ci currentWasmThread: DbThread | undefined = undefined; 159fb726d48Sopenharmony_ci 160fb726d48Sopenharmony_ci constructor(traceId: string) { 161fb726d48Sopenharmony_ci this.traceId = traceId; 162fb726d48Sopenharmony_ci } 163fb726d48Sopenharmony_ci 164fb726d48Sopenharmony_ci init = async (type: string, threadBuild: (() => DbThread) | undefined = undefined): Promise<void> => { 165fb726d48Sopenharmony_ci // wasm | server | sqlite 166fb726d48Sopenharmony_ci if (this.currentWasmThread) { 167fb726d48Sopenharmony_ci this.currentWasmThread.resetWASM(); 168fb726d48Sopenharmony_ci this.currentWasmThread = undefined; 169fb726d48Sopenharmony_ci } 170fb726d48Sopenharmony_ci await this.close(); 171fb726d48Sopenharmony_ci this.maxThreadNumber = 1; 172fb726d48Sopenharmony_ci for (let i = 0; i < this.maxThreadNumber; i++) { 173fb726d48Sopenharmony_ci let thread: DbThread | undefined; 174fb726d48Sopenharmony_ci if (threadBuild) { 175fb726d48Sopenharmony_ci thread = threadBuild(); 176fb726d48Sopenharmony_ci } else { 177fb726d48Sopenharmony_ci if (type === 'wasm') { 178fb726d48Sopenharmony_ci thread = new DbThread(new Worker(new URL('./TraceWorker', import.meta.url)), this.traceId); 179fb726d48Sopenharmony_ci } else if (type === 'server') { 180fb726d48Sopenharmony_ci thread = new DbThread(new Worker(new URL('./SqlLiteWorker', import.meta.url)), this.traceId); 181fb726d48Sopenharmony_ci } else if (type === 'sqlite') { 182fb726d48Sopenharmony_ci thread = new DbThread(new Worker(new URL('./SqlLiteWorker', import.meta.url)), this.traceId); 183fb726d48Sopenharmony_ci } 184fb726d48Sopenharmony_ci } 185fb726d48Sopenharmony_ci if (thread) { 186fb726d48Sopenharmony_ci this.currentWasmThread = thread; 187fb726d48Sopenharmony_ci thread!.worker!.onerror = (err): void => { 188fb726d48Sopenharmony_ci console.warn(err); 189fb726d48Sopenharmony_ci }; 190fb726d48Sopenharmony_ci thread!.worker!.onmessageerror = (err): void => { 191fb726d48Sopenharmony_ci console.warn(err); 192fb726d48Sopenharmony_ci }; 193fb726d48Sopenharmony_ci this.threadPostMessage(thread); 194fb726d48Sopenharmony_ci thread!.id = i; 195fb726d48Sopenharmony_ci thread!.busy = false; 196fb726d48Sopenharmony_ci this.works?.push(thread!); 197fb726d48Sopenharmony_ci } 198fb726d48Sopenharmony_ci } 199fb726d48Sopenharmony_ci }; 200fb726d48Sopenharmony_ci threadPostMessage(thread: DbThread): void { 201fb726d48Sopenharmony_ci thread!.worker!.onmessage = (event: MessageEvent): void => { 202fb726d48Sopenharmony_ci thread!.busy = false; 203fb726d48Sopenharmony_ci if (Reflect.has(thread!.taskMap, event.data.id)) { 204fb726d48Sopenharmony_ci if (event.data.results) { 205fb726d48Sopenharmony_ci let fun = thread!.taskMap[event.data.id]; 206fb726d48Sopenharmony_ci if (fun) { 207fb726d48Sopenharmony_ci fun(event.data.results, event.data.len, event.data.transfer, event.data.isEmpty); 208fb726d48Sopenharmony_ci } 209fb726d48Sopenharmony_ci Reflect.deleteProperty(thread!.taskMap, event.data.id); 210fb726d48Sopenharmony_ci } else if (Reflect.has(event.data, 'cutStatus')) { 211fb726d48Sopenharmony_ci let fun = thread!.taskMap[event.data.id]; 212fb726d48Sopenharmony_ci if (fun) { 213fb726d48Sopenharmony_ci fun(event.data); 214fb726d48Sopenharmony_ci } 215fb726d48Sopenharmony_ci } else if (Reflect.has(event.data, 'ready')) { 216fb726d48Sopenharmony_ci this.progress!('database opened', this.num + event.data.index); 217fb726d48Sopenharmony_ci this.progressTimer(this.num + event.data.index, this.progress!); 218fb726d48Sopenharmony_ci this.sharedBuffer = null; 219fb726d48Sopenharmony_ci } else if (Reflect.has(event.data, 'init')) { 220fb726d48Sopenharmony_ci if (this.cutDownTimer !== undefined) { 221fb726d48Sopenharmony_ci //@ts-ignore 222fb726d48Sopenharmony_ci clearInterval(this.cutDownTimer); 223fb726d48Sopenharmony_ci } 224fb726d48Sopenharmony_ci let fun = thread!.taskMap[event.data.id]; 225fb726d48Sopenharmony_ci if (!event.data.init && !event.data.status) { 226fb726d48Sopenharmony_ci if (fun) { 227fb726d48Sopenharmony_ci fun(['error', event.data.msg]); 228fb726d48Sopenharmony_ci } 229fb726d48Sopenharmony_ci } else { 230fb726d48Sopenharmony_ci this.progress!('database ready', 40); 231fb726d48Sopenharmony_ci if (fun) { 232fb726d48Sopenharmony_ci fun(event.data); 233fb726d48Sopenharmony_ci } 234fb726d48Sopenharmony_ci } 235fb726d48Sopenharmony_ci Reflect.deleteProperty(thread!.taskMap, event.data.id); 236fb726d48Sopenharmony_ci } else { 237fb726d48Sopenharmony_ci let fun = thread!.taskMap[event.data.id]; 238fb726d48Sopenharmony_ci if (fun) { 239fb726d48Sopenharmony_ci fun([]); 240fb726d48Sopenharmony_ci } 241fb726d48Sopenharmony_ci Reflect.deleteProperty(thread!.taskMap, event.data.id); 242fb726d48Sopenharmony_ci } 243fb726d48Sopenharmony_ci } 244fb726d48Sopenharmony_ci }; 245fb726d48Sopenharmony_ci } 246fb726d48Sopenharmony_ci 247fb726d48Sopenharmony_ci initServer = async (url: string, progress: Function): Promise<{ status: boolean; msg: string }> => { 248fb726d48Sopenharmony_ci this.progress = progress; 249fb726d48Sopenharmony_ci progress('database loaded', 15); 250fb726d48Sopenharmony_ci this.sharedBuffer = await fetch(url).then((res) => res.arrayBuffer()); 251fb726d48Sopenharmony_ci progress('open database', 20); 252fb726d48Sopenharmony_ci for (let thread of this.works) { 253fb726d48Sopenharmony_ci let { status, msg } = await thread.dbOpen(''); 254fb726d48Sopenharmony_ci if (!status) { 255fb726d48Sopenharmony_ci this.sharedBuffer = null; 256fb726d48Sopenharmony_ci return { status, msg }; 257fb726d48Sopenharmony_ci } 258fb726d48Sopenharmony_ci } 259fb726d48Sopenharmony_ci return { status: true, msg: 'ok' }; 260fb726d48Sopenharmony_ci }; 261fb726d48Sopenharmony_ci initSqlite = async ( 262fb726d48Sopenharmony_ci buf: ArrayBuffer, 263fb726d48Sopenharmony_ci parseConfig: string, 264fb726d48Sopenharmony_ci sdkWasmConfig: string, 265fb726d48Sopenharmony_ci progress: Function 266fb726d48Sopenharmony_ci ): Promise< 267fb726d48Sopenharmony_ci | { 268fb726d48Sopenharmony_ci status: false; 269fb726d48Sopenharmony_ci msg: string; 270fb726d48Sopenharmony_ci sdkConfigMap?: undefined; 271fb726d48Sopenharmony_ci } 272fb726d48Sopenharmony_ci | { 273fb726d48Sopenharmony_ci status: boolean; 274fb726d48Sopenharmony_ci msg: string; 275fb726d48Sopenharmony_ci //@ts-ignore 276fb726d48Sopenharmony_ci sdkConfigMap: unknow; 277fb726d48Sopenharmony_ci } 278fb726d48Sopenharmony_ci > => { 279fb726d48Sopenharmony_ci this.progress = progress; 280fb726d48Sopenharmony_ci progress('database loaded', 15); 281fb726d48Sopenharmony_ci this.sharedBuffer = buf; 282fb726d48Sopenharmony_ci progress('parse database', 20); 283fb726d48Sopenharmony_ci let configMap; 284fb726d48Sopenharmony_ci for (let thread of this.works) { 285fb726d48Sopenharmony_ci let { status, msg, buffer, sdkConfigMap, fileKey } = await thread.dbOpen(parseConfig, sdkWasmConfig, buf); 286fb726d48Sopenharmony_ci if (!status) { 287fb726d48Sopenharmony_ci this.sharedBuffer = null; 288fb726d48Sopenharmony_ci return { status, msg }; 289fb726d48Sopenharmony_ci } else { 290fb726d48Sopenharmony_ci configMap = sdkConfigMap; 291fb726d48Sopenharmony_ci this.sharedBuffer = buffer; 292fb726d48Sopenharmony_ci if (fileKey !== '-1') { 293fb726d48Sopenharmony_ci this.fileCacheKey = fileKey; 294fb726d48Sopenharmony_ci } else { 295fb726d48Sopenharmony_ci this.fileCacheKey = `trace/${new Date().getTime()}-${buffer.byteLength}`; 296fb726d48Sopenharmony_ci this.saveTraceFileBuffer(this.fileCacheKey, buffer).then(); 297fb726d48Sopenharmony_ci } 298fb726d48Sopenharmony_ci } 299fb726d48Sopenharmony_ci } 300fb726d48Sopenharmony_ci return { status: true, msg: 'ok', sdkConfigMap: configMap }; 301fb726d48Sopenharmony_ci }; 302fb726d48Sopenharmony_ci 303fb726d48Sopenharmony_ci async saveTraceFileBuffer(key: string, buffer: ArrayBuffer): Promise<void> { 304fb726d48Sopenharmony_ci await this.obligateFileBufferSpace(buffer.byteLength); 305fb726d48Sopenharmony_ci caches.open(key).then((cache) => { 306fb726d48Sopenharmony_ci let headers = new Headers(); 307fb726d48Sopenharmony_ci headers.append('Content-Length', `${buffer.byteLength}`); 308fb726d48Sopenharmony_ci headers.append('Content-Type', 'application/octet-stream'); 309fb726d48Sopenharmony_ci cache 310fb726d48Sopenharmony_ci .put( 311fb726d48Sopenharmony_ci key, 312fb726d48Sopenharmony_ci new Response(buffer, { 313fb726d48Sopenharmony_ci status: 200, 314fb726d48Sopenharmony_ci headers: headers, 315fb726d48Sopenharmony_ci }) 316fb726d48Sopenharmony_ci ) 317fb726d48Sopenharmony_ci .then(); 318fb726d48Sopenharmony_ci }); 319fb726d48Sopenharmony_ci } 320fb726d48Sopenharmony_ci 321fb726d48Sopenharmony_ci /** 322fb726d48Sopenharmony_ci * 计算预留缓存空间,如果空间不够,则删除部分缓存 323fb726d48Sopenharmony_ci * @param size 324fb726d48Sopenharmony_ci */ 325fb726d48Sopenharmony_ci async obligateFileBufferSpace(size: number): Promise<void> { 326fb726d48Sopenharmony_ci let es = await navigator.storage.estimate(); 327fb726d48Sopenharmony_ci let remainderByte = (es.quota || 0) - (es.usage || 0) - 20 * 1024 * 1024; 328fb726d48Sopenharmony_ci if (remainderByte < size) { 329fb726d48Sopenharmony_ci let keys = await caches.keys(); 330fb726d48Sopenharmony_ci keys.sort((keyA, keyB) => { 331fb726d48Sopenharmony_ci if (keyA.includes('/') && keyB.includes('/')) { 332fb726d48Sopenharmony_ci let splitA = keyA.split('/'); 333fb726d48Sopenharmony_ci let splitB = keyB.split('/'); 334fb726d48Sopenharmony_ci let timeA = splitA[splitA.length - 1].split('-')[0]; 335fb726d48Sopenharmony_ci let timeB = splitB[splitB.length - 1].split('-')[0]; 336fb726d48Sopenharmony_ci return parseInt(timeA) - parseInt(timeB); 337fb726d48Sopenharmony_ci } else { 338fb726d48Sopenharmony_ci return 0; 339fb726d48Sopenharmony_ci } 340fb726d48Sopenharmony_ci }); 341fb726d48Sopenharmony_ci let needSize = size - remainderByte; 342fb726d48Sopenharmony_ci for (let key of keys) { 343fb726d48Sopenharmony_ci await caches.delete(key); 344fb726d48Sopenharmony_ci let keySize = parseInt(key.split('-')[1]); 345fb726d48Sopenharmony_ci if (keySize > needSize) { 346fb726d48Sopenharmony_ci return; 347fb726d48Sopenharmony_ci } else { 348fb726d48Sopenharmony_ci needSize -= keySize; 349fb726d48Sopenharmony_ci } 350fb726d48Sopenharmony_ci } 351fb726d48Sopenharmony_ci } 352fb726d48Sopenharmony_ci } 353fb726d48Sopenharmony_ci 354fb726d48Sopenharmony_ci close = async (): Promise<void> => { 355fb726d48Sopenharmony_ci //@ts-ignore 356fb726d48Sopenharmony_ci clearInterval(this.cutDownTimer); 357fb726d48Sopenharmony_ci for (let thread of this.works) { 358fb726d48Sopenharmony_ci thread.worker?.terminate(); 359fb726d48Sopenharmony_ci } 360fb726d48Sopenharmony_ci this.works.length = 0; 361fb726d48Sopenharmony_ci }; 362fb726d48Sopenharmony_ci 363fb726d48Sopenharmony_ci async reset(): Promise<void> { 364fb726d48Sopenharmony_ci if (this.currentWasmThread) { 365fb726d48Sopenharmony_ci this.currentWasmThread.resetWASM(); 366fb726d48Sopenharmony_ci this.currentWasmThread = undefined; 367fb726d48Sopenharmony_ci } 368fb726d48Sopenharmony_ci await this.close(); 369fb726d48Sopenharmony_ci } 370fb726d48Sopenharmony_ci 371fb726d48Sopenharmony_ci //@ts-ignore 372fb726d48Sopenharmony_ci submit(name: string, sql: string, args: unknow, handler: Function, action: string | null): void { 373fb726d48Sopenharmony_ci let noBusyThreads = this.works.filter((it) => !it.busy); 374fb726d48Sopenharmony_ci let thread: DbThread; 375fb726d48Sopenharmony_ci if (noBusyThreads.length > 0) { 376fb726d48Sopenharmony_ci //取第一个空闲的线程进行任务 377fb726d48Sopenharmony_ci thread = noBusyThreads[0]; 378fb726d48Sopenharmony_ci thread.queryFunc(name, sql, args, handler, action); 379fb726d48Sopenharmony_ci } else { 380fb726d48Sopenharmony_ci // 随机插入一个线程中 381fb726d48Sopenharmony_ci thread = this.works[Math.floor(Math.random() * this.works.length)]; 382fb726d48Sopenharmony_ci thread.queryFunc(name, sql, args, handler, action); 383fb726d48Sopenharmony_ci } 384fb726d48Sopenharmony_ci } 385fb726d48Sopenharmony_ci 386fb726d48Sopenharmony_ci //@ts-ignore 387fb726d48Sopenharmony_ci submitProto(name: number, args: unknow, handler: Function): void { 388fb726d48Sopenharmony_ci let noBusyThreads = this.works.filter((it) => !it.busy); 389fb726d48Sopenharmony_ci let thread: DbThread; 390fb726d48Sopenharmony_ci if (noBusyThreads.length > 0) { 391fb726d48Sopenharmony_ci //取第一个空闲的线程进行任务 392fb726d48Sopenharmony_ci thread = noBusyThreads[0]; 393fb726d48Sopenharmony_ci thread.queryProto(name, args, handler); 394fb726d48Sopenharmony_ci } else { 395fb726d48Sopenharmony_ci // 随机插入一个线程中 396fb726d48Sopenharmony_ci thread = this.works[Math.floor(Math.random() * this.works.length)]; 397fb726d48Sopenharmony_ci if (thread) { 398fb726d48Sopenharmony_ci thread.queryProto(name, args, handler); 399fb726d48Sopenharmony_ci } 400fb726d48Sopenharmony_ci } 401fb726d48Sopenharmony_ci } 402fb726d48Sopenharmony_ci 403fb726d48Sopenharmony_ci cutFile( 404fb726d48Sopenharmony_ci leftTs: number, 405fb726d48Sopenharmony_ci rightTs: number, 406fb726d48Sopenharmony_ci handler: (status: boolean, msg: string, splitBuffer?: ArrayBuffer) => void 407fb726d48Sopenharmony_ci ): void { 408fb726d48Sopenharmony_ci let noBusyThreads = this.works.filter((it) => !it.busy); 409fb726d48Sopenharmony_ci let thread: DbThread; 410fb726d48Sopenharmony_ci if (noBusyThreads.length > 0) { 411fb726d48Sopenharmony_ci thread = noBusyThreads[0]; 412fb726d48Sopenharmony_ci thread.cutFileByRange(leftTs, rightTs, handler); 413fb726d48Sopenharmony_ci } else { 414fb726d48Sopenharmony_ci thread = this.works[Math.floor(Math.random() * this.works.length)]; 415fb726d48Sopenharmony_ci thread.cutFileByRange(leftTs, rightTs, handler); 416fb726d48Sopenharmony_ci } 417fb726d48Sopenharmony_ci } 418fb726d48Sopenharmony_ci 419fb726d48Sopenharmony_ci progressTimer(num: number, progress: Function): void { 420fb726d48Sopenharmony_ci let currentNum = num; 421fb726d48Sopenharmony_ci //@ts-ignore 422fb726d48Sopenharmony_ci clearInterval(this.cutDownTimer); 423fb726d48Sopenharmony_ci this.cutDownTimer = setInterval(() => { 424fb726d48Sopenharmony_ci currentNum += Math.floor(Math.random() * 3); 425fb726d48Sopenharmony_ci if (currentNum >= 50) { 426fb726d48Sopenharmony_ci progress('database opened', 40); 427fb726d48Sopenharmony_ci //@ts-ignore 428fb726d48Sopenharmony_ci clearInterval(this.cutDownTimer); 429fb726d48Sopenharmony_ci } else { 430fb726d48Sopenharmony_ci progress('database opened', currentNum); 431fb726d48Sopenharmony_ci } 432fb726d48Sopenharmony_ci }, Math.floor(Math.random() * 2500 + 1000)); 433fb726d48Sopenharmony_ci } 434fb726d48Sopenharmony_ci} 435fb726d48Sopenharmony_ci 436fb726d48Sopenharmony_ciexport const threadPool = new DbPool('1'); 437fb726d48Sopenharmony_ciexport const threadPool2 = new DbPool('2'); 438fb726d48Sopenharmony_ci 439fb726d48Sopenharmony_ciexport interface ThreadPoolConfig { 440fb726d48Sopenharmony_ci action?: string | null, 441fb726d48Sopenharmony_ci traceId?: string | null | undefined 442fb726d48Sopenharmony_ci} 443fb726d48Sopenharmony_ci 444fb726d48Sopenharmony_ciexport function getThreadPool(traceId?: string | null): DbPool { 445fb726d48Sopenharmony_ci return traceId === '2' ? threadPool2 : threadPool; 446fb726d48Sopenharmony_ci} 447fb726d48Sopenharmony_ci 448fb726d48Sopenharmony_ciexport function query<T>( 449fb726d48Sopenharmony_ci name: string, 450fb726d48Sopenharmony_ci sql: string, 451fb726d48Sopenharmony_ci args: unknown = null, 452fb726d48Sopenharmony_ci config?: ThreadPoolConfig 453fb726d48Sopenharmony_ci): Promise<Array<T>> { 454fb726d48Sopenharmony_ci return new Promise<Array<T>>((resolve, reject): void => { 455fb726d48Sopenharmony_ci getThreadPool(config?.traceId).submit( 456fb726d48Sopenharmony_ci name, 457fb726d48Sopenharmony_ci sql, 458fb726d48Sopenharmony_ci args, 459fb726d48Sopenharmony_ci (res: Array<T>) => { 460fb726d48Sopenharmony_ci if (res[0] && res[0] === 'error') { 461fb726d48Sopenharmony_ci window.publish(window.SmartEvent.UI.Error, res[1]); 462fb726d48Sopenharmony_ci reject(res); 463fb726d48Sopenharmony_ci } else { 464fb726d48Sopenharmony_ci resolve(res); 465fb726d48Sopenharmony_ci } 466fb726d48Sopenharmony_ci }, 467fb726d48Sopenharmony_ci config ? (config.action || null) : null 468fb726d48Sopenharmony_ci ); 469fb726d48Sopenharmony_ci }); 470fb726d48Sopenharmony_ci} 471fb726d48Sopenharmony_ci 472fb726d48Sopenharmony_ciexport function setThreadPoolTraceBuffer(traceId: string, buf: ArrayBuffer | null): void { 473fb726d48Sopenharmony_ci if (traceId === threadPool2.traceId) { 474fb726d48Sopenharmony_ci threadPool2.sharedBuffer = buf; 475fb726d48Sopenharmony_ci } else { 476fb726d48Sopenharmony_ci threadPool.sharedBuffer = buf; 477fb726d48Sopenharmony_ci } 478fb726d48Sopenharmony_ci} 479fb726d48Sopenharmony_ci 480fb726d48Sopenharmony_ciexport function getThreadPoolTraceBuffer(traceId: string): ArrayBuffer | null { 481fb726d48Sopenharmony_ci return traceId === threadPool2.traceId ? threadPool2.sharedBuffer : threadPool.sharedBuffer; 482fb726d48Sopenharmony_ci} 483fb726d48Sopenharmony_ci 484fb726d48Sopenharmony_ciexport function setThreadPoolTraceBufferCacheKey(traceId: string, key: string): void { 485fb726d48Sopenharmony_ci if (traceId === threadPool2.traceId) { 486fb726d48Sopenharmony_ci threadPool2.fileCacheKey = key; 487fb726d48Sopenharmony_ci } else { 488fb726d48Sopenharmony_ci threadPool.fileCacheKey = key; 489fb726d48Sopenharmony_ci } 490fb726d48Sopenharmony_ci} 491fb726d48Sopenharmony_ci 492fb726d48Sopenharmony_ciexport function getThreadPoolTraceBufferCacheKey(traceId: string): string { 493fb726d48Sopenharmony_ci return traceId === threadPool2.traceId ? threadPool2.fileCacheKey : threadPool.fileCacheKey; 494fb726d48Sopenharmony_ci} 495