patterncsharpMinor
A simple unrolled linked list implementation
Viewed 0 times
implementationsimpleunrolledlistlinked
Problem
I tried to implement an unrolled linked list in C#. I only needed to add things and clear the whole list so I didn't implement
Why I did it?
I needed a collection that should be able to handle millions of items and I was getting
I tried
```
public sealed class UnrolledLinkedList : IEnumerable
{
// Fields
private int _Count;
private Node _FirstNode;
private Node _LastNode;
private int _LastNodeCount;
private int _NodeCount;
private readonly int _NodeSize;
// Properties
public int Count { get { return _Count; } }
// Constructors
public UnrolledLinkedList(int nodeSize)
{
_NodeCount = 1;
_NodeSize = nodeSize;
_FirstNode = _LastNode = new Node(nodeSize);
}
public UnrolledLinkedList() : this(8) { }
// Fuctions
public void Add(T item)
{
if (_LastNodeCount == _NodeSize)
{
_LastNode = (_LastNode.Next = new Node(_NodeSize));
_LastNode.Items[0] = item;
_LastNodeCount = 1;
_NodeCount++;
}
else _LastNode.Items[_LastNodeCount++] = item;
_Count++;
}
public void Clear()
{
_FirstNode = _LastNode = new Node(_NodeSize);
// Edit: Just added these:
_Count = 0;
_LastNodeCount = 0;
_NodeCount = 1;
}
public IEnumerator GetEnumerator()
{
var current = _FirstNode;
if (current == null)
yield break;
for (; ; )
{
if (current.Next == null)
{
for (int i = 0; i < _LastNodeCount; i++)
yield re
IList (I tried but it was getting too complex, so I postponed it).Why I did it?
I needed a collection that should be able to handle millions of items and I was getting
OutOfMemoryExceptions when I tried List since it needs sequential memory to hold everything in one array.I tried
LinkedList but it was too slow. I don't need to enumerate backwards or expose the node class publicly. I also know the size of blocks that I want to keep my items in, so I wrote this:```
public sealed class UnrolledLinkedList : IEnumerable
{
// Fields
private int _Count;
private Node _FirstNode;
private Node _LastNode;
private int _LastNodeCount;
private int _NodeCount;
private readonly int _NodeSize;
// Properties
public int Count { get { return _Count; } }
// Constructors
public UnrolledLinkedList(int nodeSize)
{
_NodeCount = 1;
_NodeSize = nodeSize;
_FirstNode = _LastNode = new Node(nodeSize);
}
public UnrolledLinkedList() : this(8) { }
// Fuctions
public void Add(T item)
{
if (_LastNodeCount == _NodeSize)
{
_LastNode = (_LastNode.Next = new Node(_NodeSize));
_LastNode.Items[0] = item;
_LastNodeCount = 1;
_NodeCount++;
}
else _LastNode.Items[_LastNodeCount++] = item;
_Count++;
}
public void Clear()
{
_FirstNode = _LastNode = new Node(_NodeSize);
// Edit: Just added these:
_Count = 0;
_LastNodeCount = 0;
_NodeCount = 1;
}
public IEnumerator GetEnumerator()
{
var current = _FirstNode;
if (current == null)
yield break;
for (; ; )
{
if (current.Next == null)
{
for (int i = 0; i < _LastNodeCount; i++)
yield re
Solution
I would change
I would also remove
Finally, since you always insert an item in a
GetEnumerator as follows:public IEnumerator GetEnumerator()
{
for (var current = _FirstNode ; current != null ; )
{
var last = current.Next == null ? _NodeSize : _LastNodeCount;
for (var i = 0 ; i != last ; i++) {
yield return current.Items[i];
}
current = current.Next;
}
}I would also remove
_NodeCount, because you are maintaining it, but not using it anywhere to make decisions.Finally, since you always insert an item in a
Node, I would make Node's constructor accept the value T to be placed in Items[0], rather than keeping that code in the Add method.Code Snippets
public IEnumerator<T> GetEnumerator()
{
for (var current = _FirstNode ; current != null ; )
{
var last = current.Next == null ? _NodeSize : _LastNodeCount;
for (var i = 0 ; i != last ; i++) {
yield return current.Items[i];
}
current = current.Next;
}
}Context
StackExchange Code Review Q#17670, answer score: 6
Revisions (0)
No revisions yet.