From 7885e86836d2f5507b189a05b2b947f5c9280408 Mon Sep 17 00:00:00 2001 From: Markus Ewald Date: Mon, 13 Jul 2009 20:22:59 +0000 Subject: [PATCH] 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 --- Source/Collections/Deque.Removal.cs | 55 ++++++++++++++++------------- Source/Collections/Deque.cs | 1 + 2 files changed, 31 insertions(+), 25 deletions(-) diff --git a/Source/Collections/Deque.Removal.cs b/Source/Collections/Deque.Removal.cs index a191c8d..7438f37 100644 --- a/Source/Collections/Deque.Removal.cs +++ b/Source/Collections/Deque.Removal.cs @@ -12,7 +12,9 @@ namespace Nuclex.Support.Collections { 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; 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"); } - // 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; if(this.lastBlockEndIndex == 0) { // Block became empty if(this.count > 1) { - this.blocks.RemoveAt(this.blocks.Count - 1); + this.blocks.RemoveAt(lastBlock); this.lastBlockEndIndex = this.blockSize; } else { // Last block - do not remove this.firstBlockStartIndex = 0; @@ -65,49 +70,49 @@ namespace Nuclex.Support.Collections { /// /// Index of the item that will be removed private void removeFromLeft(int index) { - if(index == this.count - 1) { - RemoveLast(); + if(index == 0) { + RemoveFirst(); } else { int blockIndex, subIndex; findIndex(index, out blockIndex, out subIndex); - int lastBlock = this.blocks.Count - 1; - int startIndex; + int firstBlock = 0; + int endIndex; - if(blockIndex < lastBlock) { + if(blockIndex > firstBlock) { Array.Copy( - this.blocks[blockIndex], subIndex + 1, - this.blocks[blockIndex], subIndex, - this.blockSize - subIndex - 1 + this.blocks[blockIndex], 0, + this.blocks[blockIndex], 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( - this.blocks[tempIndex], 1, this.blocks[tempIndex], 0, + this.blocks[tempIndex], 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 { - startIndex = subIndex; + endIndex = subIndex; } Array.Copy( - this.blocks[lastBlock], startIndex + 1, - this.blocks[lastBlock], startIndex, - this.lastBlockEndIndex - startIndex - 1 + this.blocks[firstBlock], this.firstBlockStartIndex, + this.blocks[firstBlock], this.firstBlockStartIndex + 1, + endIndex - this.firstBlockStartIndex ); - if(this.lastBlockEndIndex == 1) { - this.blocks.RemoveAt(lastBlock); - this.lastBlockEndIndex = this.blockSize; + if(this.firstBlockStartIndex == this.blockSize - 1) { + this.blocks.RemoveAt(0); + this.firstBlockStartIndex = 0; } else { - this.blocks[lastBlock][this.lastBlockEndIndex - 1] = default(ItemType); - --this.lastBlockEndIndex; + this.blocks[0][this.firstBlockStartIndex] = default(ItemType); + ++this.firstBlockStartIndex; } --this.count; diff --git a/Source/Collections/Deque.cs b/Source/Collections/Deque.cs index 2b453e1..72d5577 100644 --- a/Source/Collections/Deque.cs +++ b/Source/Collections/Deque.cs @@ -126,6 +126,7 @@ namespace Nuclex.Support.Collections { } else { return (index - this.firstBlockStartIndex + lastBlock * this.blockSize); } + } }