| module.exports = chunkedSplice |
| |
| var v8MaxSafeChunkSize = 10000 |
| |
| // `Array#splice` takes all items to be inserted as individual argument which |
| // causes a stack overflow in V8 when trying to insert 100k items for instance. |
| function chunkedSplice(list, start, remove, items) { |
| var end = list.length |
| var chunkStart = 0 |
| var result |
| var parameters |
| |
| // Make start between zero and `end` (included). |
| if (start < 0) { |
| start = -start > end ? 0 : end + start |
| } else { |
| start = start > end ? end : start |
| } |
| |
| remove = remove > 0 ? remove : 0 |
| |
| // No need to chunk the items if there’s only a couple (10k) items. |
| if (items.length < v8MaxSafeChunkSize) { |
| parameters = Array.from(items) |
| parameters.unshift(start, remove) |
| return [].splice.apply(list, parameters) |
| } |
| |
| // Delete `remove` items starting from `start` |
| result = [].splice.apply(list, [start, remove]) |
| |
| // Insert the items in chunks to not cause stack overflows. |
| while (chunkStart < items.length) { |
| parameters = items.slice(chunkStart, chunkStart + v8MaxSafeChunkSize) |
| parameters.unshift(start, 0) |
| ;[].splice.apply(list, parameters) |
| |
| chunkStart += v8MaxSafeChunkSize |
| start += v8MaxSafeChunkSize |
| } |
| |
| return result |
| } |