@code3d/core 0.0.1-alpha.6 → 0.0.1-alpha.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -40,6 +40,7 @@ export type KernelValueLifecycle<Value> = Readonly<{
40
40
  }>;
41
41
 
42
42
  type CacheEntry<Value> = Readonly<{
43
+ persistenceEligible: boolean;
43
44
  estimatedBytes: number;
44
45
  signature: string;
45
46
  value: Value;
@@ -49,9 +50,11 @@ type CacheEntry<Value> = Readonly<{
49
50
 
50
51
  export function createComputationCache({
51
52
  maximumBytes = 2 * 1024 ** 3,
53
+ minimumPersistenceMilliseconds = 1,
52
54
  nativeAllocatedBytes,
53
55
  }: {
54
56
  maximumBytes?: number;
57
+ minimumPersistenceMilliseconds?: number;
55
58
  nativeAllocatedBytes: () => number;
56
59
  }) {
57
60
  const entries = new Map<string, CacheEntry<unknown>>();
@@ -77,6 +80,11 @@ export function createComputationCache({
77
80
  evictHistoricalEntries();
78
81
  }
79
82
 
83
+ /** Apply to future computations without changing existing entries' admission. */
84
+ function setKernelCachePersistenceThreshold(milliseconds: number): void {
85
+ minimumPersistenceMilliseconds = milliseconds;
86
+ }
87
+
80
88
  /** The host accounts for in-flight inputs and all auxiliary native heaps. */
81
89
  function setKernelExternalBytes(bytes: number): void {
82
90
  externalBytes = bytes;
@@ -134,8 +142,10 @@ export function createComputationCache({
134
142
  ): KernelArtifact<Value> {
135
143
  const hit = findKernelOperation(key, lifecycle, codec);
136
144
  if (hit) return hit;
145
+ const started = performance.now();
137
146
  const value = compute();
138
- acceptKernelOperation(key, lifecycle, value, codec);
147
+ const milliseconds = performance.now() - started;
148
+ acceptKernelOperation(key, lifecycle, value, milliseconds, codec);
139
149
  return {id: key.id, value};
140
150
  }
141
151
 
@@ -191,7 +201,9 @@ export function createComputationCache({
191
201
  misses += 1;
192
202
  return undefined;
193
203
  }
194
- cached = retainEntry(key, lifecycle, restored);
204
+ // Existing disk records have already been admitted; reading one must
205
+ // not reinterpret decode time as its original computation cost.
206
+ cached = retainEntry(key, lifecycle, restored, true);
195
207
  persistentHits += 1;
196
208
  persisted.add(id);
197
209
  }
@@ -204,7 +216,8 @@ export function createComputationCache({
204
216
  throw new Error(`Kernel operation cache identity collision: ${id}`);
205
217
  hits += 1;
206
218
  const value = cached.instantiate(cached.value);
207
- if (codec !== false) persist(key, cached.value, codec, true);
219
+ if (cached.persistenceEligible && codec !== false)
220
+ persist(key, cached.value, codec, true);
208
221
  touchEntry(id, cached as CacheEntry<unknown>);
209
222
  return {id, value};
210
223
  }
@@ -214,6 +227,7 @@ export function createComputationCache({
214
227
  key: KernelOperationKey,
215
228
  lifecycle: KernelValueLifecycle<Value>,
216
229
  value: Value,
230
+ milliseconds: number,
217
231
  codec?: CacheCodec<Value> | false,
218
232
  ): void {
219
233
  const existing = entries.get(key.id);
@@ -230,8 +244,14 @@ export function createComputationCache({
230
244
  lifecycle.release(value);
231
245
  throw error;
232
246
  }
233
- const entry = retainEntry(key, lifecycle, retained);
234
- if (codec !== false) persist(key, retained, codec);
247
+ const entry = retainEntry(
248
+ key,
249
+ lifecycle,
250
+ retained,
251
+ milliseconds >= minimumPersistenceMilliseconds,
252
+ );
253
+ if (entry.persistenceEligible && codec !== false)
254
+ persist(key, retained, codec);
235
255
  touchEntry(key.id, entry as CacheEntry<unknown>);
236
256
  }
237
257
 
@@ -288,8 +308,10 @@ export function createComputationCache({
288
308
  key: KernelOperationKey,
289
309
  lifecycle: KernelValueLifecycle<Value>,
290
310
  retained: Value,
311
+ persistenceEligible: boolean,
291
312
  ): CacheEntry<Value> {
292
313
  const entry: CacheEntry<Value> = {
314
+ persistenceEligible,
293
315
  estimatedBytes:
294
316
  256 +
295
317
  estimateRetainedBytes(key.signature) +
@@ -375,6 +397,7 @@ export function createComputationCache({
375
397
  clearKernelOperationCache,
376
398
  kernelOperationCacheStats,
377
399
  setKernelCacheBudget,
400
+ setKernelCachePersistenceThreshold,
378
401
  setKernelArtifactStore,
379
402
  findKernelOperation,
380
403
  findKernelOperations,
@@ -396,6 +419,7 @@ export const {
396
419
  clearKernelOperationCache,
397
420
  kernelOperationCacheStats,
398
421
  setKernelCacheBudget,
422
+ setKernelCachePersistenceThreshold,
399
423
  setKernelArtifactStore,
400
424
  findKernelOperation,
401
425
  findKernelOperations,
@@ -32,7 +32,7 @@ import {
32
32
  transformGeometry,
33
33
  type AlignmentGeometry,
34
34
  } from './alignment-geometry.js';
35
- import {cached, cachedArtifact} from './cached.js';
35
+ import {cache, cachedArtifact} from './cached.js';
36
36
  import {extrudeWithTopology} from './extrude.js';
37
37
  import {font, googleFont, type Font} from './font.js';
38
38
  import {
@@ -4851,7 +4851,11 @@ export type SnapshotQueryBatch = Readonly<{
4851
4851
  weight: number;
4852
4852
  sourceRef?: SourceRef;
4853
4853
  encode(): Uint8Array;
4854
- accept(query: SnapshotQuery, value: SnapshotQueryResult): void;
4854
+ accept(
4855
+ query: SnapshotQuery,
4856
+ value: SnapshotQueryResult,
4857
+ milliseconds: number,
4858
+ ): void;
4855
4859
  }>;
4856
4860
 
4857
4861
  export function planModelSnapshotQueries(
@@ -4907,7 +4911,8 @@ export function planModelSnapshotQueries(
4907
4911
  (input.geometry.topology?.surfaces.ids.length ?? 0)) *
4908
4912
  queries.length,
4909
4913
  encode: () => encodeKernelArtifact(id, input.geometry),
4910
- accept: (query, value) => snapshotQuery.accept(query.key, value),
4914
+ accept: (query, value, milliseconds) =>
4915
+ snapshotQuery.accept(query.key, value, milliseconds),
4911
4916
  }));
4912
4917
  }
4913
4918
 
@@ -4917,7 +4922,11 @@ export function executeSnapshotQueryBatch(
4917
4922
  bytes: Uint8Array,
4918
4923
  queries: readonly SnapshotQuery[],
4919
4924
  checkCancelled: () => void,
4920
- onResult: (query: SnapshotQuery, value: SnapshotQueryResult) => void,
4925
+ onResult: (
4926
+ query: SnapshotQuery,
4927
+ value: SnapshotQueryResult,
4928
+ milliseconds: number,
4929
+ ) => void,
4921
4930
  onRestore?: (milliseconds: number) => void,
4922
4931
  ): void {
4923
4932
  const started = performance.now();
@@ -4929,7 +4938,9 @@ export function executeSnapshotQueryBatch(
4929
4938
  onRestore?.(performance.now() - started);
4930
4939
  for (const query of queries) {
4931
4940
  checkCancelled();
4932
- onResult(query, computeSnapshotQuery(geometry, query));
4941
+ const started = performance.now();
4942
+ const value = computeSnapshotQuery(geometry, query);
4943
+ onResult(query, value, performance.now() - started);
4933
4944
  }
4934
4945
  } finally {
4935
4946
  geometry.shape.delete();
@@ -5012,7 +5023,7 @@ export const authoringApi = Object.freeze({
5012
5023
  pivotPoint,
5013
5024
  axisEdge,
5014
5025
  axisLine,
5015
- cached,
5026
+ cache,
5016
5027
  font,
5017
5028
  googleFont,
5018
5029
  text,
@@ -10,6 +10,7 @@ export {
10
10
  clearKernelOperationCache,
11
11
  kernelOperationCacheStats,
12
12
  setKernelCacheBudget,
13
+ setKernelCachePersistenceThreshold,
13
14
  setKernelArtifactStore,
14
15
  setKernelExternalBytes,
15
16
  } from '../library/kernel-cache.js';