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_ciimport { DbPool, getThreadPoolTraceBufferCacheKey, setThreadPoolTraceBuffer } from './SqlLite';
17fb726d48Sopenharmony_ci
18fb726d48Sopenharmony_ciclass ConvertThread {
19fb726d48Sopenharmony_ci  isCancelled: boolean = false;
20fb726d48Sopenharmony_ci  id: number = -1;
21fb726d48Sopenharmony_ci  taskMap: unknown = {};
22fb726d48Sopenharmony_ci  name: string | undefined;
23fb726d48Sopenharmony_ci  worker?: Worker;
24fb726d48Sopenharmony_ci  busy: boolean = false;
25fb726d48Sopenharmony_ci  constructor(worker: Worker) {
26fb726d48Sopenharmony_ci    this.worker = worker;
27fb726d48Sopenharmony_ci  }
28fb726d48Sopenharmony_ci  uuid(): string {
29fb726d48Sopenharmony_ci    // @ts-ignore
30fb726d48Sopenharmony_ci    return ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, (c) =>
31fb726d48Sopenharmony_ci      (c ^ (crypto.getRandomValues(new Uint8Array(1))[0] & (15 >> (c / 4)))).toString(16)
32fb726d48Sopenharmony_ci    );
33fb726d48Sopenharmony_ci  }
34fb726d48Sopenharmony_ci
35fb726d48Sopenharmony_ci  getConvertData(handler: (status: boolean, msg: string, results: Blob) => void): void {
36fb726d48Sopenharmony_ci    this.busy = true;
37fb726d48Sopenharmony_ci    let id = this.uuid();
38fb726d48Sopenharmony_ci    // @ts-ignore
39fb726d48Sopenharmony_ci    this.taskMap[id] = (res: unknown): void => {
40fb726d48Sopenharmony_ci      // @ts-ignore
41fb726d48Sopenharmony_ci      setThreadPoolTraceBuffer('1', res.buffer);
42fb726d48Sopenharmony_ci      // @ts-ignore
43fb726d48Sopenharmony_ci      handler(res.status, res.msg, res.results);
44fb726d48Sopenharmony_ci    };
45fb726d48Sopenharmony_ci    caches.match(getThreadPoolTraceBufferCacheKey('1')).then((resData) => {
46fb726d48Sopenharmony_ci      if (resData) {
47fb726d48Sopenharmony_ci        resData.arrayBuffer().then((buffer) => {
48fb726d48Sopenharmony_ci          this.worker!.postMessage(
49fb726d48Sopenharmony_ci            {
50fb726d48Sopenharmony_ci              id: id,
51fb726d48Sopenharmony_ci              action: 'getConvertData',
52fb726d48Sopenharmony_ci              buffer: buffer!,
53fb726d48Sopenharmony_ci            },
54fb726d48Sopenharmony_ci            [buffer!]
55fb726d48Sopenharmony_ci          );
56fb726d48Sopenharmony_ci        });
57fb726d48Sopenharmony_ci      }
58fb726d48Sopenharmony_ci    });
59fb726d48Sopenharmony_ci  }
60fb726d48Sopenharmony_ci}
61fb726d48Sopenharmony_ci
62fb726d48Sopenharmony_ciclass ConvertPool {
63fb726d48Sopenharmony_ci  maxThreadNumber: number = 0;
64fb726d48Sopenharmony_ci  works: Array<ConvertThread> = [];
65fb726d48Sopenharmony_ci  progress: Function | undefined | null;
66fb726d48Sopenharmony_ci  static data: Array<string> = [];
67fb726d48Sopenharmony_ci  num = Math.floor(Math.random() * 10 + 1) + 20;
68fb726d48Sopenharmony_ci  init = async (type: string): Promise<void> => {
69fb726d48Sopenharmony_ci    // server
70fb726d48Sopenharmony_ci    await this.close();
71fb726d48Sopenharmony_ci    if (type === 'convert') {
72fb726d48Sopenharmony_ci      this.maxThreadNumber = 1;
73fb726d48Sopenharmony_ci    }
74fb726d48Sopenharmony_ci    for (let i = 0; i < this.maxThreadNumber; i++) {
75fb726d48Sopenharmony_ci      let thread: ConvertThread;
76fb726d48Sopenharmony_ci      if (type === 'convert') {
77fb726d48Sopenharmony_ci        thread = new ConvertThread(new Worker(new URL('./ConvertTraceWorker', import.meta.url)));
78fb726d48Sopenharmony_ci      }
79fb726d48Sopenharmony_ci      thread!.worker!.onmessage = (event: MessageEvent): void => {
80fb726d48Sopenharmony_ci        thread.busy = false;
81fb726d48Sopenharmony_ci        ConvertPool.data = event.data.results;
82fb726d48Sopenharmony_ci        // @ts-ignore
83fb726d48Sopenharmony_ci        if (Reflect.has(thread.taskMap, event.data.id)) {
84fb726d48Sopenharmony_ci          if (event.data.results) {
85fb726d48Sopenharmony_ci            // @ts-ignore
86fb726d48Sopenharmony_ci            let fun = thread.taskMap[event.data.id];
87fb726d48Sopenharmony_ci            if (fun) {
88fb726d48Sopenharmony_ci              fun(event.data);
89fb726d48Sopenharmony_ci            }
90fb726d48Sopenharmony_ci            // @ts-ignore
91fb726d48Sopenharmony_ci            Reflect.deleteProperty(thread.taskMap, event.data.id);
92fb726d48Sopenharmony_ci          } else {
93fb726d48Sopenharmony_ci            // @ts-ignore
94fb726d48Sopenharmony_ci            let fun = thread.taskMap[event.data.id];
95fb726d48Sopenharmony_ci            if (fun) {
96fb726d48Sopenharmony_ci              fun([]);
97fb726d48Sopenharmony_ci            }
98fb726d48Sopenharmony_ci            // @ts-ignore
99fb726d48Sopenharmony_ci            Reflect.deleteProperty(thread.taskMap, event.data.id);
100fb726d48Sopenharmony_ci          }
101fb726d48Sopenharmony_ci        }
102fb726d48Sopenharmony_ci      };
103fb726d48Sopenharmony_ci      thread!.worker!.onmessageerror = (e): void => {};
104fb726d48Sopenharmony_ci      thread!.worker!.onerror = (e): void => {};
105fb726d48Sopenharmony_ci      thread!.id = i;
106fb726d48Sopenharmony_ci      thread!.busy = false;
107fb726d48Sopenharmony_ci      this.works?.push(thread!);
108fb726d48Sopenharmony_ci    }
109fb726d48Sopenharmony_ci  };
110fb726d48Sopenharmony_ci
111fb726d48Sopenharmony_ci  clearCache = (): void => {
112fb726d48Sopenharmony_ci    for (let i = 0; i < this.works.length; i++) {
113fb726d48Sopenharmony_ci      let thread = this.works[i];
114fb726d48Sopenharmony_ci      thread.getConvertData(() => {});
115fb726d48Sopenharmony_ci    }
116fb726d48Sopenharmony_ci  };
117fb726d48Sopenharmony_ci
118fb726d48Sopenharmony_ci  close = async (): Promise<void> => {
119fb726d48Sopenharmony_ci    for (let i = 0; i < this.works.length; i++) {
120fb726d48Sopenharmony_ci      let thread = this.works[i];
121fb726d48Sopenharmony_ci      thread.worker!.terminate();
122fb726d48Sopenharmony_ci    }
123fb726d48Sopenharmony_ci    this.works.length = 0;
124fb726d48Sopenharmony_ci  };
125fb726d48Sopenharmony_ci
126fb726d48Sopenharmony_ci  // @ts-ignore
127fb726d48Sopenharmony_ci  submitWithName(
128fb726d48Sopenharmony_ci    name: string,
129fb726d48Sopenharmony_ci    handler: (status: boolean, msg: string, results: Blob) => void
130fb726d48Sopenharmony_ci  ): ConvertThread | undefined {
131fb726d48Sopenharmony_ci    let noBusyThreads = this.works;
132fb726d48Sopenharmony_ci    let thread: ConvertThread | undefined;
133fb726d48Sopenharmony_ci    if (noBusyThreads.length > 0) {
134fb726d48Sopenharmony_ci      //取第一个空闲的线程进行任务
135fb726d48Sopenharmony_ci      thread = noBusyThreads[0];
136fb726d48Sopenharmony_ci      thread!.getConvertData(handler);
137fb726d48Sopenharmony_ci    }
138fb726d48Sopenharmony_ci    return thread;
139fb726d48Sopenharmony_ci  }
140fb726d48Sopenharmony_ci
141fb726d48Sopenharmony_ci  isIdle(): boolean {
142fb726d48Sopenharmony_ci    return this.works.every((it) => !it.busy);
143fb726d48Sopenharmony_ci  }
144fb726d48Sopenharmony_ci}
145fb726d48Sopenharmony_ci
146fb726d48Sopenharmony_ciexport const convertPool = new ConvertPool();
147