chunked.ts 1.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546
  1. /**
  2. * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
  3. *
  4. * @author David Sehnal <david.sehnal@gmail.com>
  5. */
  6. import { now } from 'mol-util/now';
  7. import { RuntimeContext } from '../execution/runtime-context'
  8. type UniformlyChunkedFn<S> = (chunkSize: number, state: S) => number
  9. async function chunkedSubtask<S>(ctx: RuntimeContext, initialChunk: number, state: S,
  10. f: UniformlyChunkedFn<S>, update: (ctx: RuntimeContext, state: S, processed: number) => Promise<void> | void): Promise<S> {
  11. let chunkSize = Math.max(initialChunk, 0);
  12. let globalProcessed = 0, globalTime = 0;
  13. if (ctx.isSynchronous) {
  14. f(Number.MAX_SAFE_INTEGER, state);
  15. return state;
  16. }
  17. let start = now();
  18. let lastSize = 0, currentTime = 0;
  19. while ((lastSize = f(chunkSize, state)) > 0) {
  20. globalProcessed += lastSize;
  21. const delta = now() - start;
  22. currentTime += delta;
  23. globalTime += delta;
  24. if (ctx.shouldUpdate) {
  25. await update(ctx, state, globalProcessed);
  26. chunkSize = Math.round(currentTime * globalProcessed / globalTime) + 1;
  27. start = now();
  28. currentTime = 0;
  29. }
  30. }
  31. if (ctx.shouldUpdate) {
  32. await update(ctx, state, globalProcessed);
  33. }
  34. return state;
  35. }
  36. export { chunkedSubtask }