chunked-splice.mjs 1.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344
  1. export default chunkedSplice
  2. import constants from '../constant/constants.mjs'
  3. import splice from '../constant/splice.mjs'
  4. // `Array#splice` takes all items to be inserted as individual argument which
  5. // causes a stack overflow in V8 when trying to insert 100k items for instance.
  6. function chunkedSplice(list, start, remove, items) {
  7. var end = list.length
  8. var chunkStart = 0
  9. var parameters
  10. // Make start between zero and `end` (included).
  11. if (start < 0) {
  12. start = -start > end ? 0 : end + start
  13. } else {
  14. start = start > end ? end : start
  15. }
  16. remove = remove > 0 ? remove : 0
  17. // No need to chunk the items if there’s only a couple (10k) items.
  18. if (items.length < constants.v8MaxSafeChunkSize) {
  19. parameters = Array.from(items)
  20. parameters.unshift(start, remove)
  21. splice.apply(list, parameters)
  22. } else {
  23. // Delete `remove` items starting from `start`
  24. if (remove) splice.apply(list, [start, remove])
  25. // Insert the items in chunks to not cause stack overflows.
  26. while (chunkStart < items.length) {
  27. parameters = items.slice(
  28. chunkStart,
  29. chunkStart + constants.v8MaxSafeChunkSize
  30. )
  31. parameters.unshift(start, 0)
  32. splice.apply(list, parameters)
  33. chunkStart += constants.v8MaxSafeChunkSize
  34. start += constants.v8MaxSafeChunkSize
  35. }
  36. }
  37. }