array-fixed
Advanced tools
Comparing version 0.6.0 to 0.7.0
@@ -513,11 +513,4 @@ 'use strict'; | ||
indexStart = Math.max(indexStart + this._array.length, 0); | ||
} | ||
if (this._direction) { | ||
if (indexStart > this._count) { | ||
indexStart = this._count; | ||
} | ||
} else { | ||
if (indexStart < this._array.length - this._count - 1) { | ||
indexStart = this._array.length - this._count - 1; | ||
} | ||
indexStart = Math.min(indexStart, this._array.length); | ||
} | ||
@@ -530,5 +523,27 @@ // deleteCount is set to the rest of the array if only indexStart is set | ||
deleteCount = deleteCount | 0; | ||
// the minimum deleteCount is 0 | ||
deleteCount = Math.max(deleteCount, 0); | ||
// the maximum deleteCount is the length where the indexStart starts | ||
deleteCount = Math.min(deleteCount, this._array.length - indexStart); | ||
} | ||
if (deleteCount !== items.length) { | ||
throw RangeError('Splicing will result in underflow or overflow'); | ||
// for dense arrays | ||
// the splice range may be at the empty range | ||
// if so, in order to efficiently splice | ||
// we need to shift the indexStart | ||
// to be adjacent to the filled range | ||
// however we cannot do this if the | ||
// splice range includes an empty element | ||
// as that would be against the semantics of splice | ||
if (this._direction) { | ||
// if the beginning of the splice is empty | ||
// shift the indexStart to the end of a left-dense array | ||
if (!this._array.hasOwnProperty(indexStart)) { | ||
indexStart = this._count; | ||
} | ||
} else { | ||
// if the end of the splice is empty | ||
// shift the indexStart to the start + deleteCount of a right-dense array | ||
if (!this._array.hasOwnProperty(indexStart + deleteCount - 1)) { | ||
indexStart = this._array.length - this._count - deleteCount; | ||
} | ||
} | ||
@@ -540,5 +555,27 @@ // count how many set items are deleted | ||
} | ||
if (this._count - deletedCount + items.length > this._array.length) { | ||
throw RangeError('Splicing will result in overflow'); | ||
} | ||
const lengthOrig = this._array.length; | ||
const deletedItems = this._array.splice(indexStart, deleteCount, ...items); | ||
// a left dense array can be easily readjusted by truncation | ||
// a right dense array is more complicated | ||
// either we pad the array from the left using concat | ||
// or we have to memmove the contents to the left | ||
// and then truncate | ||
if (this._direction) { | ||
// truncate the array to the appropriate length | ||
this._array.length = lengthOrig; | ||
} else { | ||
if (deleteCount > items.length) { | ||
// pad the array from the left | ||
this._array = new Array(Math.min(deleteCount - items.length, lengthOrig)).concat(this._array); | ||
} else if (deleteCount < items.length) { | ||
// move the array left then truncate | ||
this._array.copyWithin(0, this._array.length - lengthOrig); | ||
this._array.length = lengthOrig; | ||
} | ||
} | ||
this._count += items.length - deletedCount; | ||
const deletedItems = this._array.splice(indexStart, deleteCount, ...items); | ||
return ArrayFixedDense.fromArray(deletedItems, deletedItems.length, this._direction); | ||
return ArrayFixedDense.fromArray(deletedItems, deletedCount, this._direction); | ||
} | ||
@@ -545,0 +582,0 @@ |
@@ -507,11 +507,4 @@ import _slicedToArray from 'babel-runtime/helpers/slicedToArray'; | ||
indexStart = Math.max(indexStart + this._array.length, 0); | ||
} | ||
if (this._direction) { | ||
if (indexStart > this._count) { | ||
indexStart = this._count; | ||
} | ||
} else { | ||
if (indexStart < this._array.length - this._count - 1) { | ||
indexStart = this._array.length - this._count - 1; | ||
} | ||
indexStart = Math.min(indexStart, this._array.length); | ||
} | ||
@@ -524,5 +517,27 @@ // deleteCount is set to the rest of the array if only indexStart is set | ||
deleteCount = deleteCount | 0; | ||
// the minimum deleteCount is 0 | ||
deleteCount = Math.max(deleteCount, 0); | ||
// the maximum deleteCount is the length where the indexStart starts | ||
deleteCount = Math.min(deleteCount, this._array.length - indexStart); | ||
} | ||
if (deleteCount !== items.length) { | ||
throw RangeError('Splicing will result in underflow or overflow'); | ||
// for dense arrays | ||
// the splice range may be at the empty range | ||
// if so, in order to efficiently splice | ||
// we need to shift the indexStart | ||
// to be adjacent to the filled range | ||
// however we cannot do this if the | ||
// splice range includes an empty element | ||
// as that would be against the semantics of splice | ||
if (this._direction) { | ||
// if the beginning of the splice is empty | ||
// shift the indexStart to the end of a left-dense array | ||
if (!this._array.hasOwnProperty(indexStart)) { | ||
indexStart = this._count; | ||
} | ||
} else { | ||
// if the end of the splice is empty | ||
// shift the indexStart to the start + deleteCount of a right-dense array | ||
if (!this._array.hasOwnProperty(indexStart + deleteCount - 1)) { | ||
indexStart = this._array.length - this._count - deleteCount; | ||
} | ||
} | ||
@@ -534,5 +549,27 @@ // count how many set items are deleted | ||
} | ||
if (this._count - deletedCount + items.length > this._array.length) { | ||
throw RangeError('Splicing will result in overflow'); | ||
} | ||
const lengthOrig = this._array.length; | ||
const deletedItems = this._array.splice(indexStart, deleteCount, ...items); | ||
// a left dense array can be easily readjusted by truncation | ||
// a right dense array is more complicated | ||
// either we pad the array from the left using concat | ||
// or we have to memmove the contents to the left | ||
// and then truncate | ||
if (this._direction) { | ||
// truncate the array to the appropriate length | ||
this._array.length = lengthOrig; | ||
} else { | ||
if (deleteCount > items.length) { | ||
// pad the array from the left | ||
this._array = new Array(Math.min(deleteCount - items.length, lengthOrig)).concat(this._array); | ||
} else if (deleteCount < items.length) { | ||
// move the array left then truncate | ||
this._array.copyWithin(0, this._array.length - lengthOrig); | ||
this._array.length = lengthOrig; | ||
} | ||
} | ||
this._count += items.length - deletedCount; | ||
const deletedItems = this._array.splice(indexStart, deleteCount, ...items); | ||
return ArrayFixedDense.fromArray(deletedItems, deletedItems.length, this._direction); | ||
return ArrayFixedDense.fromArray(deletedItems, deletedCount, this._direction); | ||
} | ||
@@ -539,0 +576,0 @@ |
@@ -181,11 +181,4 @@ // @flow | ||
indexStart = Math.max(indexStart + this._array.length, 0); | ||
} | ||
if (this._direction) { | ||
if (indexStart > this._count) { | ||
indexStart = this._count; | ||
} | ||
} else { | ||
if (indexStart < this._array.length - this._count - 1) { | ||
indexStart = this._array.length - this._count - 1; | ||
} | ||
indexStart = Math.min(indexStart, this._array.length); | ||
} | ||
@@ -198,5 +191,27 @@ // deleteCount is set to the rest of the array if only indexStart is set | ||
deleteCount = deleteCount|0; | ||
// the minimum deleteCount is 0 | ||
deleteCount = Math.max(deleteCount, 0); | ||
// the maximum deleteCount is the length where the indexStart starts | ||
deleteCount = Math.min(deleteCount, this._array.length - indexStart); | ||
} | ||
if (deleteCount !== items.length) { | ||
throw RangeError('Splicing will result in underflow or overflow'); | ||
// for dense arrays | ||
// the splice range may be at the empty range | ||
// if so, in order to efficiently splice | ||
// we need to shift the indexStart | ||
// to be adjacent to the filled range | ||
// however we cannot do this if the | ||
// splice range includes an empty element | ||
// as that would be against the semantics of splice | ||
if (this._direction) { | ||
// if the beginning of the splice is empty | ||
// shift the indexStart to the end of a left-dense array | ||
if (!this._array.hasOwnProperty(indexStart)) { | ||
indexStart = this._count; | ||
} | ||
} else { | ||
// if the end of the splice is empty | ||
// shift the indexStart to the start + deleteCount of a right-dense array | ||
if (!this._array.hasOwnProperty(indexStart + deleteCount - 1)) { | ||
indexStart = this._array.length - this._count - deleteCount; | ||
} | ||
} | ||
@@ -208,7 +223,31 @@ // count how many set items are deleted | ||
} | ||
if (this._count - deletedCount + items.length > this._array.length) { | ||
throw RangeError('Splicing will result in overflow'); | ||
} | ||
const lengthOrig = this._array.length; | ||
const deletedItems = this._array.splice(indexStart, deleteCount, ...items); | ||
// a left dense array can be easily readjusted by truncation | ||
// a right dense array is more complicated | ||
// either we pad the array from the left using concat | ||
// or we have to memmove the contents to the left | ||
// and then truncate | ||
if (this._direction) { | ||
// truncate the array to the appropriate length | ||
this._array.length = lengthOrig; | ||
} else { | ||
if (deleteCount > items.length) { | ||
// pad the array from the left | ||
this._array = (new Array( | ||
Math.min(deleteCount - items.length, lengthOrig) | ||
)).concat(this._array); | ||
} else if (deleteCount < items.length) { | ||
// move the array left then truncate | ||
this._array.copyWithin(0, this._array.length - lengthOrig); | ||
this._array.length = lengthOrig; | ||
} | ||
} | ||
this._count += items.length - deletedCount; | ||
const deletedItems = this._array.splice(indexStart, deleteCount, ...items); | ||
return ArrayFixedDense.fromArray( | ||
deletedItems, | ||
deletedItems.length, | ||
deletedCount, | ||
this._direction | ||
@@ -215,0 +254,0 @@ ); |
{ | ||
"name": "array-fixed", | ||
"version": "0.6.0", | ||
"version": "0.7.0", | ||
"description": "Array with a Fixed Preallocated Length", | ||
@@ -5,0 +5,0 @@ "keywords": [ |
# ArrayFixed | ||
`ArrayFixed` is a fixed length sparse JavaScript array. The main advantage of a fixed length sparse array, is that we maintain a count along with the array length. Extending on the fixed length sparse array, we create a fixed length sparse array that is dense in one direction (left or right). The `ArrayFixedDense` ensures that the array is kept dense in one particular direction. | ||
In order to lift the direction of `ArrayFixedDense` into the type system, we added `direction` boolean to the type. So you can set `ArrayFixedDense<*, true>` to ensure that we have a left dense array, or `ArrayFixedDense<*, false>` to ensure we have a right dense array. | ||
However due to a flow problem, this doesn't quite work yet: https://github.com/facebook/flow/issues/5848 |
Sorry, the diff of this file is too big to display
139684
3688
4