diff --git a/incremental/common/src/index.ts b/incremental/common/src/index.ts index 45bd3d454c903864bdca34d57fc580da66c39cea..fa91fbf70c7445d23189047bf0f17af1110bc7aa 100644 --- a/incremental/common/src/index.ts +++ b/incremental/common/src/index.ts @@ -42,7 +42,7 @@ export { int8Array, errorAsString, unsafeCast, - CoroutineLocalValue, + WorkerLocalValue, scheduleCoroutine, memoryStats, launchJob diff --git a/incremental/compat/src/arkts/utils.ts b/incremental/compat/src/arkts/utils.ts index ec855ec898564683a16314c9a42ca7adf74030ea..d21116f6ce382f5c501148c44519d3e8bba4329c 100644 --- a/incremental/compat/src/arkts/utils.ts +++ b/incremental/compat/src/arkts/utils.ts @@ -39,16 +39,4 @@ export function launchJob(task: () => void): Promise { return taskpool.execute(task) } -export class CoroutineLocalValue { - private map = new containers.ConcurrentHashMap - get(): T | undefined { - return this.map.get(CoroutineExtras.getWorkerId()) - } - set(value: T | undefined) { - if (value) { - this.map.set(CoroutineExtras.getWorkerId(), value) - } else { - this.map.delete(CoroutineExtras.getWorkerId()) - } - } -} +export type WorkerLocalValue = WorkerLocal diff --git a/incremental/compat/src/index.ts b/incremental/compat/src/index.ts index d068f170afefa359a4ac4d8fd1f976dca122fd50..eb7a6130a7f3f43743b8631c0d8906c3d9205f32 100644 --- a/incremental/compat/src/index.ts +++ b/incremental/compat/src/index.ts @@ -55,7 +55,7 @@ export { int8Array, errorAsString, unsafeCast, - CoroutineLocalValue, + WorkerLocalValue, scheduleCoroutine, memoryStats, launchJob diff --git a/incremental/compat/src/ohos/index.ts b/incremental/compat/src/ohos/index.ts index 892265e6691bc3bd0423b50d01327d3293bc1952..4d454e8bdd307e087ecf6b32636ce7036ba1275a 100644 --- a/incremental/compat/src/ohos/index.ts +++ b/incremental/compat/src/ohos/index.ts @@ -53,7 +53,7 @@ export { int8Array, errorAsString, unsafeCast, - CoroutineLocalValue, + WorkerLocalValue, scheduleCoroutine, memoryStats, launchJob diff --git a/incremental/compat/src/typescript/utils.ts b/incremental/compat/src/typescript/utils.ts index 1169707fa520b1284d29a1a5d3f7422460d31a4e..b6c0cfcfe89bc5c7edc561ea21a82de079bf7d97 100644 --- a/incremental/compat/src/typescript/utils.ts +++ b/incremental/compat/src/typescript/utils.ts @@ -13,6 +13,8 @@ * limitations under the License. */ +import { AtomicRef } from "./atomic" + export function errorAsString(error: any): string { if (error instanceof Error) { return error.stack ?? error.toString() @@ -41,12 +43,46 @@ export function launchJob(task: () => void): Promise { }) } -export class CoroutineLocalValue { - private value: T | undefined = undefined - get(): T | undefined { - return this.value +export class WorkerLocalValue { + private ref?: AtomicRef + + /** + * @param init - a factory function to provide initial worker-local value if needed + */ + constructor(private init?: () => T) { + } + + /** + * @returns the worker-local value for current worker + * @throws `Error` when value not initialized and no `init` function provided + */ + get(): T { + const ref = this.ref + if (ref) return ref.value + const init = this.init + if (!init) throw new Error("WorkerLocalValue not initialized: call set() first or provide init() function.") + const value = init() + this.ref = new AtomicRef(value) + return value } - set(value: T | undefined) { - this.value = value + + /** + * Updates the worker-local value for current worker. + * @param value - new value to store + */ + set(value: T) { + const ref = this.ref + if (ref) { + ref.value = value + } else { + this.ref = new AtomicRef(value) + } + } + + /** + * Deletes the worker-local value for current worker. + */ + delete() { + this.ref = undefined } } diff --git a/incremental/runtime/src/states/State.ts b/incremental/runtime/src/states/State.ts index e094481714cf2f0b9cf31be18513c37d8b3407ae..e01615d290dd6ad46edb8d9645986fc74d94eaf6 100644 --- a/incremental/runtime/src/states/State.ts +++ b/incremental/runtime/src/states/State.ts @@ -16,7 +16,7 @@ import { Array_from_set, className, - CoroutineLocalValue, + WorkerLocalValue, float64toInt32, int32, KoalaCallsiteKey, @@ -54,7 +54,7 @@ export function createStateManager(): StateManager { return new StateManagerImpl() } -export const StateManagerLocal = new CoroutineLocalValue() +export const StateManagerLocal = new WorkerLocalValue(() => undefined) /** * State manager, core of incremental runtime engine.