The deque's RemoveAt() method now shifts the objects in the direction that produces the least amount of work
git-svn-id: file:///srv/devel/repo-conversion/nusu@161 d2e56fa2-650e-0410-a79f-9358c0239efd
This commit is contained in:
parent
58c3254260
commit
7885e86836
|
@ -12,7 +12,9 @@ namespace Nuclex.Support.Collections {
|
||||||
throw new InvalidOperationException("Cannot remove items from empty deque");
|
throw new InvalidOperationException("Cannot remove items from empty deque");
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Zero removed array entry if array is kept
|
// This is necessary to make sure the deque doesn't hold dead objects alive
|
||||||
|
// in unreachable spaces of its memory.
|
||||||
|
this.blocks[0][this.firstBlockStartIndex] = default(ItemType);
|
||||||
|
|
||||||
++this.firstBlockStartIndex;
|
++this.firstBlockStartIndex;
|
||||||
if(this.firstBlockStartIndex >= this.blockSize) { // Block became empty
|
if(this.firstBlockStartIndex >= this.blockSize) { // Block became empty
|
||||||
|
@ -33,12 +35,15 @@ namespace Nuclex.Support.Collections {
|
||||||
throw new InvalidOperationException("Cannot remove items from empty deque");
|
throw new InvalidOperationException("Cannot remove items from empty deque");
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Zero removed array entry if array is kept
|
// This is necessary to make sure the deque doesn't hold dead objects alive
|
||||||
|
// in unreachable spaces of its memory.
|
||||||
|
int lastBlock = this.blocks.Count - 1;
|
||||||
|
this.blocks[lastBlock][this.lastBlockEndIndex - 1] = default(ItemType);
|
||||||
|
|
||||||
--this.lastBlockEndIndex;
|
--this.lastBlockEndIndex;
|
||||||
if(this.lastBlockEndIndex == 0) { // Block became empty
|
if(this.lastBlockEndIndex == 0) { // Block became empty
|
||||||
if(this.count > 1) {
|
if(this.count > 1) {
|
||||||
this.blocks.RemoveAt(this.blocks.Count - 1);
|
this.blocks.RemoveAt(lastBlock);
|
||||||
this.lastBlockEndIndex = this.blockSize;
|
this.lastBlockEndIndex = this.blockSize;
|
||||||
} else { // Last block - do not remove
|
} else { // Last block - do not remove
|
||||||
this.firstBlockStartIndex = 0;
|
this.firstBlockStartIndex = 0;
|
||||||
|
@ -65,49 +70,49 @@ namespace Nuclex.Support.Collections {
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="index">Index of the item that will be removed</param>
|
/// <param name="index">Index of the item that will be removed</param>
|
||||||
private void removeFromLeft(int index) {
|
private void removeFromLeft(int index) {
|
||||||
if(index == this.count - 1) {
|
if(index == 0) {
|
||||||
RemoveLast();
|
RemoveFirst();
|
||||||
} else {
|
} else {
|
||||||
int blockIndex, subIndex;
|
int blockIndex, subIndex;
|
||||||
findIndex(index, out blockIndex, out subIndex);
|
findIndex(index, out blockIndex, out subIndex);
|
||||||
|
|
||||||
int lastBlock = this.blocks.Count - 1;
|
int firstBlock = 0;
|
||||||
int startIndex;
|
int endIndex;
|
||||||
|
|
||||||
if(blockIndex < lastBlock) {
|
if(blockIndex > firstBlock) {
|
||||||
Array.Copy(
|
Array.Copy(
|
||||||
this.blocks[blockIndex], subIndex + 1,
|
this.blocks[blockIndex], 0,
|
||||||
this.blocks[blockIndex], subIndex,
|
this.blocks[blockIndex], 1,
|
||||||
this.blockSize - subIndex - 1
|
subIndex
|
||||||
);
|
);
|
||||||
this.blocks[blockIndex][this.blockSize - 1] = this.blocks[blockIndex + 1][0];
|
this.blocks[blockIndex][0] = this.blocks[blockIndex - 1][this.blockSize - 1];
|
||||||
|
|
||||||
for(int tempIndex = blockIndex + 1; tempIndex < lastBlock; ++tempIndex) {
|
for(int tempIndex = blockIndex - 1; tempIndex > firstBlock; --tempIndex) {
|
||||||
Array.Copy(
|
Array.Copy(
|
||||||
this.blocks[tempIndex], 1,
|
|
||||||
this.blocks[tempIndex], 0,
|
this.blocks[tempIndex], 0,
|
||||||
|
this.blocks[tempIndex], 1,
|
||||||
this.blockSize - 1
|
this.blockSize - 1
|
||||||
);
|
);
|
||||||
this.blocks[tempIndex][this.blockSize - 1] = this.blocks[tempIndex + 1][0];
|
this.blocks[tempIndex][0] = this.blocks[tempIndex - 1][this.blockSize - 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
startIndex = 0;
|
endIndex = this.blockSize - 1;
|
||||||
} else {
|
} else {
|
||||||
startIndex = subIndex;
|
endIndex = subIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
Array.Copy(
|
Array.Copy(
|
||||||
this.blocks[lastBlock], startIndex + 1,
|
this.blocks[firstBlock], this.firstBlockStartIndex,
|
||||||
this.blocks[lastBlock], startIndex,
|
this.blocks[firstBlock], this.firstBlockStartIndex + 1,
|
||||||
this.lastBlockEndIndex - startIndex - 1
|
endIndex - this.firstBlockStartIndex
|
||||||
);
|
);
|
||||||
|
|
||||||
if(this.lastBlockEndIndex == 1) {
|
if(this.firstBlockStartIndex == this.blockSize - 1) {
|
||||||
this.blocks.RemoveAt(lastBlock);
|
this.blocks.RemoveAt(0);
|
||||||
this.lastBlockEndIndex = this.blockSize;
|
this.firstBlockStartIndex = 0;
|
||||||
} else {
|
} else {
|
||||||
this.blocks[lastBlock][this.lastBlockEndIndex - 1] = default(ItemType);
|
this.blocks[0][this.firstBlockStartIndex] = default(ItemType);
|
||||||
--this.lastBlockEndIndex;
|
++this.firstBlockStartIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
--this.count;
|
--this.count;
|
||||||
|
|
|
@ -126,6 +126,7 @@ namespace Nuclex.Support.Collections {
|
||||||
} else {
|
} else {
|
||||||
return (index - this.firstBlockStartIndex + lastBlock * this.blockSize);
|
return (index - this.firstBlockStartIndex + lastBlock * this.blockSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user